Compare commits
4 Commits
constraint
...
shader-cac
Author | SHA1 | Date | |
---|---|---|---|
|
e8d497b83a | ||
|
37767e056f | ||
|
c7e1ab67c6 | ||
|
4a2e73a07c |
1
.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/subprojects/*/
|
125
.gitlab-ci.yml
@@ -1,120 +1,43 @@
|
||||
stages:
|
||||
- build
|
||||
- flatpak
|
||||
- deploy
|
||||
|
||||
.cache-paths: &cache-paths
|
||||
paths:
|
||||
- _ccache/
|
||||
- subprojects/gdk-pixbuf/
|
||||
- subprojects/glib/
|
||||
- subprojects/graphene/
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
|
||||
gtk:
|
||||
image: ebassi/gitlab-gtk:latest
|
||||
stage: build
|
||||
before_script:
|
||||
- export CCACHE_DISABLE=true_
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
cache:
|
||||
paths:
|
||||
- subprojects/gdk-pixbuf/
|
||||
- subprojects/glib/
|
||||
- subprojects/graphene/
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
junit:
|
||||
- "${CI_PROJECT_DIR}/_build/report.xml"
|
||||
when: on_failure
|
||||
name: "gtk-${CI_COMMIT_REF_NAME}"
|
||||
paths:
|
||||
- "${CI_PROJECT_DIR}/_build/meson-logs"
|
||||
- "${CI_PROJECT_DIR}/_build/report.xml"
|
||||
- "${CI_PROJECT_DIR}/_build/report.html"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/reftests/output/*.png"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/gsk/compare/*/*.png"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
|
||||
.mingw-defaults: &mingw-defaults
|
||||
stage: build
|
||||
tags:
|
||||
- win32
|
||||
script:
|
||||
- C:\msys64\usr\bin\pacman --noconfirm -Syyuu
|
||||
- C:\msys64\usr\bin\bash -lc "bash -x ./.gitlab-ci/test-msys2.sh"
|
||||
cache:
|
||||
key: "%CI_JOB_NAME%"
|
||||
<<: *cache-paths
|
||||
|
||||
msys2-mingw32:
|
||||
variables:
|
||||
MSYSTEM: "MINGW32"
|
||||
CHERE_INVOKING: "yes"
|
||||
<<: *mingw-defaults
|
||||
|
||||
.flatpak-defaults: &flatpak-defaults
|
||||
image: registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:master
|
||||
flatpak:demo:
|
||||
image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
|
||||
stage: flatpak
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh org.gtk.Demo
|
||||
artifacts:
|
||||
paths:
|
||||
- "${APPID}-dev.flatpak"
|
||||
- org.gtk.Demo-dev.flatpak
|
||||
expire_in: 1 day
|
||||
|
||||
flatpak:widget-factory:
|
||||
image: registry.gitlab.com/alatiera/gnome-nightly-oci/gnome-master:latest
|
||||
stage: flatpak
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
||||
|
||||
# Manual jobs, for branches and MRs
|
||||
.flatpak-manual: &flatpak-manual
|
||||
<<: *flatpak-defaults
|
||||
when: manual
|
||||
|
||||
# Only build Flatpak bundles automatically on master
|
||||
.flatpak-master: &flatpak-master
|
||||
<<: *flatpak-defaults
|
||||
only:
|
||||
- master
|
||||
|
||||
flatpak-manual:demo:
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
<<: *flatpak-manual
|
||||
|
||||
flatpak-master:demo:
|
||||
variables:
|
||||
APPID: org.gtk.Demo4
|
||||
<<: *flatpak-master
|
||||
|
||||
flatpak-manual:widget-factory:
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
<<: *flatpak-manual
|
||||
|
||||
flatpak-master:widget-factory:
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory4
|
||||
<<: *flatpak-master
|
||||
|
||||
flatpak-manual:icon-browser:
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
<<: *flatpak-manual
|
||||
|
||||
flatpak-master:icon-browser:
|
||||
variables:
|
||||
APPID: org.gtk.IconBrowser4
|
||||
<<: *flatpak-master
|
||||
|
||||
pages:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v6
|
||||
stage: deploy
|
||||
script:
|
||||
- meson -Ddocumentation=true _build .
|
||||
- ninja -C _build
|
||||
- ninja -C _build gdk4-doc gsk4-doc gtk4-doc
|
||||
|
||||
- mkdir -p public/
|
||||
- mv _build/docs/reference/gtk/html/ public/gtk/
|
||||
- mv _build/docs/reference/gdk/html/ public/gdk/
|
||||
- mv _build/docs/reference/gsk/html/ public/gsk/
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh org.gtk.WidgetFactory
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- master
|
||||
- org.gtk.WidgetFactory-dev.flatpak
|
||||
expire_in: 1 day
|
||||
|
@@ -1,7 +1,6 @@
|
||||
FROM fedora:30
|
||||
FROM fedora:27
|
||||
|
||||
RUN dnf -y install \
|
||||
hicolor-icon-theme \
|
||||
adwaita-icon-theme \
|
||||
atk-devel \
|
||||
at-spi2-atk-devel \
|
||||
@@ -11,8 +10,6 @@ RUN dnf -y install \
|
||||
ccache \
|
||||
colord-devel \
|
||||
cups-devel \
|
||||
dbus-daemon \
|
||||
dejavu-sans-mono-fonts \
|
||||
desktop-file-utils \
|
||||
elfutils-libelf-devel \
|
||||
fribidi-devel \
|
||||
@@ -31,11 +28,9 @@ RUN dnf -y install \
|
||||
gstreamer1-plugins-good \
|
||||
gstreamer1-plugins-bad-free-devel \
|
||||
gstreamer1-plugins-base-devel \
|
||||
gtk-doc \
|
||||
iso-codes \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
lcov \
|
||||
libattr-devel \
|
||||
libepoxy-devel \
|
||||
libffi-devel \
|
||||
@@ -60,7 +55,6 @@ RUN dnf -y install \
|
||||
pango-devel \
|
||||
pcre-devel \
|
||||
python3 \
|
||||
python3-jinja2 \
|
||||
python3-pip \
|
||||
python3-wheel \
|
||||
redhat-rpm-config \
|
||||
@@ -73,7 +67,7 @@ RUN dnf -y install \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf clean all
|
||||
|
||||
RUN pip3 install meson==0.50.1
|
||||
RUN pip3 install meson
|
||||
|
||||
ARG HOST_USER_ID=5555
|
||||
ENV HOST_USER_ID ${HOST_USER_ID}
|
||||
|
@@ -1,363 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Turns a Mason testlog.json file into an HTML report
|
||||
#
|
||||
# Copyright 2019 GNOME Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# Original author: Emmanuele Bassi
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from jinja2 import Template
|
||||
|
||||
REPORT_TEMPLATE = '''
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ report.project_name }} Test Report</title>
|
||||
<meta charset="utf-8" />
|
||||
<style type="text/css">
|
||||
body {
|
||||
background: white;
|
||||
color: #333;
|
||||
font-family: 'Cantarell', sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #333333;
|
||||
font-size: 1.9em;
|
||||
font-weight: normal;
|
||||
margin-bottom: 1em;
|
||||
border-bottom: 1px solid #333333;
|
||||
}
|
||||
|
||||
header {
|
||||
position: fixed;
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 24px;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
box-shadow: 0 0 1px rgba(0, 0, 0, 0.15);
|
||||
z-index: 500;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
transform: translateY(0px);
|
||||
transition: .2s background-color, color;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
article {
|
||||
padding-top: 200px;
|
||||
margin: 2em;
|
||||
}
|
||||
|
||||
div.report-meta {
|
||||
width: auto;
|
||||
border: 1px solid #ccc;
|
||||
padding: .5em 2em;
|
||||
color: #3c3c3c;
|
||||
}
|
||||
|
||||
span.result {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.pass {
|
||||
color: rgb(51, 209, 122);
|
||||
}
|
||||
|
||||
span.skip {
|
||||
color: rgb(255, 163, 72);
|
||||
}
|
||||
|
||||
span.fail {
|
||||
color: rgb(224, 27, 36);
|
||||
}
|
||||
|
||||
span.xfail {
|
||||
color: rgb(163, 71, 186);
|
||||
}
|
||||
|
||||
div.result {
|
||||
border-top: 1px solid #c0c0c0;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.result h4 {
|
||||
border-bottom: 1px solid #c0c0c0;
|
||||
margin-bottom: 0.7em;
|
||||
}
|
||||
|
||||
pre {
|
||||
color: #fafafa;
|
||||
background-color: black;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0px 5px 8px 0px rgba(0, 0, 0, 0.25);
|
||||
font-family: monospace;
|
||||
line-height: 1.2em;
|
||||
border: none;
|
||||
padding: 10px 1em;
|
||||
font-size: 0.9em;
|
||||
overflow: auto;
|
||||
white-space: pre;
|
||||
word-break: normal;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
ul.passed li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
ul.passed li:after {
|
||||
content: ",";
|
||||
}
|
||||
|
||||
ul.passed li:last-child:after {
|
||||
content: "";
|
||||
}
|
||||
|
||||
ul.images {
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
|
||||
ul.images li {
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>{{ report.project_name }} :: Test Reports</h1>
|
||||
<div class="report-meta">
|
||||
<p><strong>Branch:</strong> {{ report.branch_name }}</p>
|
||||
<p><strong>Date:</strong> <time datetime="{{ report.date.isoformat() }}">{{ report.locale_date }}</time></p>
|
||||
{% if report.job_id %}<p><strong>Job ID:</strong> {{ report.job_id }}</p>{% endif %}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<section>
|
||||
<div class="summary">
|
||||
<h3>Summary</h3>
|
||||
<ul>
|
||||
<li><strong>Total units:</strong> {{ report.total_units }}</li>
|
||||
<li><strong>Passed:</strong> {{ report.total_successes }}</li>
|
||||
<li><strong>Failed:</strong> {{ report.total_failures }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% for suite_result in report.results_list %}
|
||||
<section>
|
||||
<div class="result">
|
||||
<h3>Suite: {{ suite_result.suite_name }}</h3>
|
||||
<ul>
|
||||
<li><strong>Units:</strong> {{ suite_result.n_units }}</li>
|
||||
<li><strong>Passed:</strong> {{ suite_result.n_successes }}</li>
|
||||
<li><strong>Failed:</strong> {{ suite_result.n_failures }}</li>
|
||||
</ul>
|
||||
|
||||
<div class="successes">
|
||||
<h4>Passed</h4>
|
||||
<ul class="passed">
|
||||
{% for success in suite_result.successes if success.result == 'OK' %}
|
||||
<li>{{ success.name }} - result: <span class="result pass">{{ success.result }}</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Skipped</h4>
|
||||
<ul>
|
||||
{% for success in suite_result.successes if success.result == 'SKIP' %}
|
||||
<li>{{ success.name }} - result: <span class="result skip">{{ success.result }}</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Expected failures</h4>
|
||||
<ul>
|
||||
{% for success in suite_result.successes if success.result == 'EXPECTEDFAIL' %}
|
||||
<li>{{ success.name }} - result: <span class="result xfail">{{ success.result }}</span><br/>
|
||||
{% if success.stdout %}
|
||||
Output: <pre>{{ success.stdout }}</pre>
|
||||
{% endif %}
|
||||
{% if success.image_data is defined %}
|
||||
<ul class="images">
|
||||
<li><img alt="ref" src="{{ success.image_data.ref }}" /></li>
|
||||
<li><img alt="out" src="{{ success.image_data.out }}" /></li>
|
||||
<li><img alt="diff" src="{{ success.image_data.diff }}" /></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="failures">
|
||||
<h4>Failed</h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'FAIL' %}
|
||||
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
{% if failure.stdout %}
|
||||
Output: <pre>{{ failure.stdout }}</pre>
|
||||
{% endif %}
|
||||
{% if failure.image_data is defined %}
|
||||
<ul class="images">
|
||||
<li><img alt="ref" src="{{ failure.image_data.ref }}" /></li>
|
||||
<li><img alt="out" src="{{ failure.image_data.out }}" /></li>
|
||||
<li><img alt="diff" src="{{ failure.image_data.diff }}" /></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h4>Timed out</h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'TIMEOUT' %}
|
||||
<li>{{ failure.name }} - result: <span class="result fail">{{ failure.result }}</span><br/>
|
||||
{% if failure.stdout %}
|
||||
Output: <pre>{{ failure.stdout }}</pre>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% else %}
|
||||
<li>None</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
{% endfor %}
|
||||
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
|
||||
aparser = argparse.ArgumentParser(description='Turns a Meson test log into an HTML report')
|
||||
aparser.add_argument('--project-name', metavar='NAME',
|
||||
help='The project name',
|
||||
default='Unknown')
|
||||
aparser.add_argument('--job-id', metavar='ID',
|
||||
help='The job ID for the report',
|
||||
default=None)
|
||||
aparser.add_argument('--branch', metavar='NAME',
|
||||
help='Branch of the project being tested',
|
||||
default='master')
|
||||
aparser.add_argument('--output', metavar='FILE',
|
||||
help='The output HTML file, stdout by default',
|
||||
type=argparse.FileType('w', encoding='UTF-8'),
|
||||
default=sys.stdout)
|
||||
aparser.add_argument('--reftest-suite', metavar='NAME',
|
||||
help='The name of the reftests suite',
|
||||
default='reftest')
|
||||
aparser.add_argument('--reftest-output-dir', metavar='DIR',
|
||||
help='The output directory for reftests data',
|
||||
default=None)
|
||||
aparser.add_argument('infile', metavar='FILE',
|
||||
help='The input testlog.json, stdin by default',
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
default=sys.stdin)
|
||||
|
||||
args = aparser.parse_args()
|
||||
|
||||
outfile = args.output
|
||||
|
||||
suites = {}
|
||||
for line in args.infile:
|
||||
data = json.loads(line)
|
||||
(full_suite, unit_name) = data['name'].split(' / ')
|
||||
(project_name, suite_name) = full_suite.split(':')
|
||||
|
||||
unit = {
|
||||
'project-name': project_name,
|
||||
'suite': suite_name,
|
||||
'name': unit_name,
|
||||
'duration': data['duration'],
|
||||
'returncode': data['returncode'],
|
||||
'result': data['result'],
|
||||
'stdout': data['stdout'],
|
||||
}
|
||||
|
||||
if args.reftest_output_dir is not None and suite_name == args.reftest_suite:
|
||||
filename = unit_name.split(' ')[1]
|
||||
basename = os.path.splitext(filename)[0]
|
||||
|
||||
image_data = {
|
||||
'ref': os.path.join(args.reftest_output_dir, '{}.ref.png'.format(basename)),
|
||||
'out': os.path.join(args.reftest_output_dir, '{}.out.png'.format(basename)),
|
||||
'diff': os.path.join(args.reftest_output_dir, '{}.diff.png'.format(basename)),
|
||||
}
|
||||
|
||||
unit['image_data'] = image_data
|
||||
|
||||
units = suites.setdefault(full_suite, [])
|
||||
units.append(unit)
|
||||
|
||||
report = {}
|
||||
report['date'] = datetime.datetime.utcnow()
|
||||
report['locale_date'] = report['date'].strftime("%c")
|
||||
report['project_name'] = args.project_name
|
||||
report['job_id'] = args.job_id
|
||||
report['branch_name'] = args.branch
|
||||
report['total_successes'] = 0
|
||||
report['total_failures'] = 0
|
||||
report['total_units'] = 0
|
||||
report['results_list'] = []
|
||||
|
||||
for name, units in suites.items():
|
||||
(project_name, suite_name) = name.split(':')
|
||||
print('Processing {} suite {}:'.format(project_name, suite_name))
|
||||
|
||||
def if_failed(unit):
|
||||
if unit['result'] in ['FAIL', 'TIMEOUT']:
|
||||
return True
|
||||
return False
|
||||
|
||||
def if_succeded(unit):
|
||||
if unit['result'] in ['OK', 'EXPECTEDFAIL', 'SKIP']:
|
||||
return True
|
||||
return False
|
||||
|
||||
successes = list(filter(if_succeded, units))
|
||||
failures = list(filter(if_failed, units))
|
||||
|
||||
n_units = len(units)
|
||||
n_successes = len(successes)
|
||||
n_failures = len(failures)
|
||||
|
||||
report['total_units'] += n_units
|
||||
report['total_successes'] += n_successes
|
||||
report['total_failures'] += n_failures
|
||||
print(' - {}: {} total, {} pass, {} fail'.format(suite_name, n_units, n_successes, n_failures))
|
||||
|
||||
suite_report = {
|
||||
'suite_name': suite_name,
|
||||
'n_units': n_units,
|
||||
'successes': successes,
|
||||
'n_successes': n_successes,
|
||||
'failures': failures,
|
||||
'n_failures': n_failures,
|
||||
}
|
||||
report['results_list'].append(suite_report)
|
||||
|
||||
template = Template(REPORT_TEMPLATE)
|
||||
outfile.write(template.render({'report': report}))
|
@@ -1,109 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Turns a Meson testlog.json file into a JUnit XML report
|
||||
#
|
||||
# Copyright 2019 GNOME Foundation
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# Original author: Emmanuele Bassi
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
aparser = argparse.ArgumentParser(description='Turns a Meson test log into a JUnit report')
|
||||
aparser.add_argument('--project-name', metavar='NAME',
|
||||
help='The project name',
|
||||
default='unknown')
|
||||
aparser.add_argument('--job-id', metavar='ID',
|
||||
help='The job ID for the report',
|
||||
default='Unknown')
|
||||
aparser.add_argument('--branch', metavar='NAME',
|
||||
help='Branch of the project being tested',
|
||||
default='master')
|
||||
aparser.add_argument('--output', metavar='FILE',
|
||||
help='The output file, stdout by default',
|
||||
type=argparse.FileType('w', encoding='UTF-8'),
|
||||
default=sys.stdout)
|
||||
aparser.add_argument('infile', metavar='FILE',
|
||||
help='The input testlog.json, stdin by default',
|
||||
type=argparse.FileType('r', encoding='UTF-8'),
|
||||
default=sys.stdin)
|
||||
|
||||
args = aparser.parse_args()
|
||||
|
||||
outfile = args.output
|
||||
|
||||
testsuites = ET.Element('testsuites')
|
||||
testsuites.set('id', '{}/{}'.format(args.job_id, args.branch))
|
||||
testsuites.set('package', args.project_name)
|
||||
testsuites.set('timestamp', datetime.datetime.utcnow().isoformat(timespec='minutes'))
|
||||
|
||||
suites = {}
|
||||
for line in args.infile:
|
||||
data = json.loads(line)
|
||||
(full_suite, unit_name) = data['name'].split(' / ')
|
||||
(project_name, suite_name) = full_suite.split(':')
|
||||
|
||||
duration = data['duration']
|
||||
return_code = data['returncode']
|
||||
log = data['stdout']
|
||||
|
||||
unit = {
|
||||
'suite': suite_name,
|
||||
'name': unit_name,
|
||||
'duration': duration,
|
||||
'returncode': return_code,
|
||||
'stdout': log,
|
||||
}
|
||||
|
||||
units = suites.setdefault(suite_name, [])
|
||||
units.append(unit)
|
||||
|
||||
for name, units in suites.items():
|
||||
print('Processing suite {} (units: {})'.format(name, len(units)))
|
||||
|
||||
def if_failed(unit):
|
||||
if unit['returncode'] != 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def if_succeded(unit):
|
||||
if unit['returncode'] == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
successes = list(filter(if_succeded, units))
|
||||
failures = list(filter(if_failed, units))
|
||||
print(' - {}: {} pass, {} fail'.format(name, len(successes), len(failures)))
|
||||
|
||||
testsuite = ET.SubElement(testsuites, 'testsuite')
|
||||
testsuite.set('name', '{}/{}'.format(args.project_name, name))
|
||||
testsuite.set('tests', str(len(units)))
|
||||
testsuite.set('errors', str(len(failures)))
|
||||
testsuite.set('failures', str(len(failures)))
|
||||
|
||||
for unit in successes:
|
||||
testcase = ET.SubElement(testsuite, 'testcase')
|
||||
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
||||
testcase.set('name', unit['name'])
|
||||
testcase.set('time', str(unit['duration']))
|
||||
|
||||
for unit in failures:
|
||||
testcase = ET.SubElement(testsuite, 'testcase')
|
||||
testcase.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
||||
testcase.set('name', unit['name'])
|
||||
testcase.set('time', str(unit['duration']))
|
||||
|
||||
failure = ET.SubElement(testcase, 'failure')
|
||||
failure.set('classname', '{}/{}'.format(args.project_name, unit['suite']))
|
||||
failure.set('name', unit['name'])
|
||||
failure.set('type', 'error')
|
||||
failure.text = unit['stdout']
|
||||
|
||||
output = ET.tostring(testsuites, encoding='unicode')
|
||||
outfile.write(output)
|
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v6"
|
||||
TAG="ebassi/gitlab-gtk:latest"
|
||||
|
||||
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||
--file "Dockerfile" .
|
||||
|
@@ -4,51 +4,20 @@ set -e
|
||||
|
||||
srcdir=$(pwd)
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
|
||||
ccache --zero-stats
|
||||
ccache --show-stats
|
||||
export CCACHE_DISABLE=true
|
||||
meson \
|
||||
-Dx11-backend=true \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
--werror \
|
||||
_build $srcdir
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
cd _build
|
||||
|
||||
ninja
|
||||
ccache --show-stats
|
||||
|
||||
set +e
|
||||
|
||||
xvfb-run -a -s "-screen 0 1024x768x24" \
|
||||
meson test \
|
||||
--timeout-multiplier 2 \
|
||||
--print-errorlogs \
|
||||
--suite=gtk \
|
||||
--no-suite=gtk:a11y
|
||||
|
||||
# Save the exit code
|
||||
exit_code=$?
|
||||
|
||||
# We always want to run the report generators
|
||||
$srcdir/.gitlab-ci/meson-junit-report.py \
|
||||
--project-name=gtk \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--output=report.xml \
|
||||
meson-logs/testlog.json
|
||||
|
||||
$srcdir/.gitlab-ci/meson-html-report.py \
|
||||
--project-name=GTK \
|
||||
--job-id="${CI_JOB_NAME}" \
|
||||
--reftest-output-dir="testsuite/reftests/output" \
|
||||
--output=report.html \
|
||||
meson-logs/testlog.json
|
||||
|
||||
exit $exit_code
|
||||
--suite=gtk+ \
|
||||
--no-suite=gtk+:gsk \
|
||||
--no-suite=gtk+:a11y
|
||||
|
@@ -1,54 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$MSYSTEM" == "MINGW32" ]]; then
|
||||
export MSYS2_ARCH="i686"
|
||||
else
|
||||
export MSYS2_ARCH="x86_64"
|
||||
fi
|
||||
|
||||
# Update everything
|
||||
pacman --noconfirm -Suy
|
||||
|
||||
# Install the required packages
|
||||
pacman --noconfirm -S --needed \
|
||||
base-devel \
|
||||
git \
|
||||
mingw-w64-$MSYS2_ARCH-toolchain \
|
||||
mingw-w64-$MSYS2_ARCH-ccache \
|
||||
mingw-w64-$MSYS2_ARCH-pkg-config \
|
||||
mingw-w64-$MSYS2_ARCH-gobject-introspection \
|
||||
mingw-w64-$MSYS2_ARCH-meson \
|
||||
mingw-w64-$MSYS2_ARCH-adwaita-icon-theme \
|
||||
mingw-w64-$MSYS2_ARCH-atk \
|
||||
mingw-w64-$MSYS2_ARCH-cairo \
|
||||
mingw-w64-$MSYS2_ARCH-gdk-pixbuf2 \
|
||||
mingw-w64-$MSYS2_ARCH-glib2 \
|
||||
mingw-w64-$MSYS2_ARCH-graphene \
|
||||
mingw-w64-$MSYS2_ARCH-json-glib \
|
||||
mingw-w64-$MSYS2_ARCH-libepoxy \
|
||||
mingw-w64-$MSYS2_ARCH-pango \
|
||||
mingw-w64-$MSYS2_ARCH-fribidi \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
|
||||
# Build
|
||||
ccache --zero-stats
|
||||
ccache --show-stats
|
||||
export CCACHE_DISABLE=true
|
||||
meson \
|
||||
-Dx11-backend=false \
|
||||
-Dwayland-backend=false \
|
||||
-Dwin32-backend=true \
|
||||
-Dvulkan=no \
|
||||
--werror \
|
||||
_build
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
ninja -C _build
|
||||
ccache --show-stats
|
@@ -7,8 +7,8 @@
|
||||
<!--
|
||||
You should try and reproduce with the demos applications available
|
||||
under the `demos` directory, or the test programs in the `tests` directory.
|
||||
Alternatively, please attach a *small and self-contained* example
|
||||
*written in C* that exhibits the issue.
|
||||
Alternatively, please attach a *small and self-contained* example that
|
||||
exhibits the issue.
|
||||
-->
|
||||
|
||||
## Current behavior
|
||||
@@ -23,14 +23,17 @@
|
||||
|
||||
## Version information
|
||||
<!--
|
||||
- Which version of GTK you are using
|
||||
- What operating system and version
|
||||
- For Linux, which distribution
|
||||
- If you built GTK yourself, the list of options used to configure the build
|
||||
- which version of GTK+ you are using
|
||||
- what operating system and version
|
||||
- for Linux, which distribution
|
||||
- if you built GTK+ yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Additional information
|
||||
<!--
|
||||
- Screenshots or screen recordings are useful for visual errors
|
||||
- Please report any warning or message printed on the terminal
|
||||
-->
|
||||
- If the bug was a crash, the exact text that was printed out
|
||||
when the crash occurred.
|
||||
- If the bug was a crash, attaching a stack trace obtained using
|
||||
GDB is appreciated; follow the instructions on the wiki:
|
||||
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces
|
||||
-->
|
@@ -1,34 +0,0 @@
|
||||
## Steps to reproduce
|
||||
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
|
||||
<!--
|
||||
You should try and reproduce with the demos applications available
|
||||
under the `demos` directory, or the test programs in the `tests` directory.
|
||||
Alternatively, please attach a *small and self-contained* example that
|
||||
exhibits the issue.
|
||||
-->
|
||||
|
||||
## Version information
|
||||
<!--
|
||||
- Which version of GTK you are using
|
||||
- What operating system and version
|
||||
- for Linux, which distribution
|
||||
- If you built GTK yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Warnings
|
||||
<!--
|
||||
- If the application generates warning messages before crashing please
|
||||
report them here
|
||||
-->
|
||||
|
||||
## Backtrace
|
||||
<!--
|
||||
- Attaching a stack trace obtained using GDB is appreciated; follow the
|
||||
instructions on the wiki:
|
||||
|
||||
https://wiki.gnome.org/Community/GettingInTouch/Bugzilla/GettingTraces
|
||||
-->
|
241
CONTRIBUTING.md
@@ -1,144 +1,31 @@
|
||||
# Contribution guidelines
|
||||
|
||||
Thank you for considering contributing to the GTK project!
|
||||
|
||||
These guidelines are meant for new contributors, regardless of their level
|
||||
of proficiency; following them allows the maintainers of the GTK project to
|
||||
more effectively evaluate your contribution, and provide prompt feedback to
|
||||
you. Additionally, by following these guidelines you clearly communicate
|
||||
that you respect the time and effort that the people developing GTK put into
|
||||
managing the project.
|
||||
|
||||
GTK is a complex free software GUI toolkit, and it would not exist without
|
||||
contributions from the free and open source software community. There are
|
||||
many things that we value:
|
||||
|
||||
- bug reporting and fixing
|
||||
- documentation and examples
|
||||
- tests
|
||||
- new features
|
||||
|
||||
Please, do not use the issue tracker for support questions. If you have
|
||||
questions on how to use GTK effectively, you can use:
|
||||
|
||||
- the `#gtk` IRC channel on irc.gnome.org
|
||||
- the [gtk](https://mail.gnome.org/mailman/listinfo/gtk-list) mailing list,
|
||||
for general questions on GTK
|
||||
- the [gtk-app-devel](https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list)
|
||||
mailing list, for questions on application development with GTK
|
||||
- the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
||||
mailing list, for questions on developing GTK itself
|
||||
|
||||
You can also look at the GTK tag on [Stack
|
||||
Overflow](https://stackoverflow.com/questions/tagged/gtk).
|
||||
|
||||
The issue tracker is meant to be used for actionable issues only.
|
||||
|
||||
## How to report bugs
|
||||
|
||||
### Security issues
|
||||
|
||||
You should not open a new issue for security related questions.
|
||||
|
||||
When in doubt, send an email to the [security](mailto:security@gnome.org)
|
||||
mailing list.
|
||||
|
||||
### Bug reports
|
||||
|
||||
If you're reporting a bug make sure to list:
|
||||
|
||||
0. which version of GTK are you using?
|
||||
0. which operating system are you using?
|
||||
0. the necessary steps to reproduce the issue
|
||||
0. the expected outcome
|
||||
0. a description of the behavior; screenshots are also welcome
|
||||
0. a small, self-contained example exhibiting the behavior; if this
|
||||
is not available, try reproducing the issue using the GTK examples
|
||||
or interactive tests
|
||||
|
||||
If the issue includes a crash, you should also include:
|
||||
|
||||
0. the eventual warnings printed on the terminal
|
||||
0. a backtrace, obtained with tools such as GDB or LLDB
|
||||
|
||||
For small issues, such as:
|
||||
|
||||
- spelling/grammar fixes in the documentation
|
||||
- typo correction
|
||||
- comment clean ups
|
||||
- changes to metadata files (CI, `.gitignore`)
|
||||
- build system changes
|
||||
- source tree clean ups and reorganizations
|
||||
|
||||
You should directly open a merge request instead of filing a new issue.
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
Feature discussion can be open ended and require high bandwidth channels; if
|
||||
you are proposing a new feature on the issue tracker, make sure to make
|
||||
an actionable proposal, and list:
|
||||
|
||||
0. what you're trying to achieve
|
||||
0. prior art, in other toolkits or applications
|
||||
0. design and theming changes
|
||||
|
||||
If you're proposing the integration of new features it helps to have
|
||||
multiple applications using shared or similar code, especially if they have
|
||||
iterated over it various times.
|
||||
|
||||
Each feature should also come fully documented, and with tests.
|
||||
|
||||
## Your first contribution
|
||||
|
||||
### Prerequisites
|
||||
|
||||
If you want to contribute to the GTK project, you will need to have the
|
||||
development tools appropriate for your operating system, including:
|
||||
If you want to hack on the GTK+ project, you'll need to have the development
|
||||
tools appropriate for your operating system, including:
|
||||
|
||||
- Python 3.x
|
||||
- Meson
|
||||
- Ninja
|
||||
- Gettext (19.7 or newer)
|
||||
- a [C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||
- a C99 compatible compiler
|
||||
|
||||
Up-to-date instructions about developing GNOME applications and libraries
|
||||
can be found on [the GNOME Developer Center](https://developer.gnome.org).
|
||||
can be found here:
|
||||
|
||||
The GTK project uses GitLab for code hosting and for tracking issues. More
|
||||
information about using GitLab can be found [on the GNOME
|
||||
wiki](https://wiki.gnome.org/GitLab).
|
||||
* https://developer.gnome.org
|
||||
|
||||
### Dependencies
|
||||
Information about using GitLab with GNOME can be found here:
|
||||
|
||||
In order to get GTK from Git installed on your system, you need to have the
|
||||
required versions of all the software dependencies required by GTK; typically,
|
||||
this means a recent version of GLib, Cairo, Pango, and ATK, as well as the
|
||||
platform-specific dependencies for the windowing system you are using (Wayland,
|
||||
X11, Windows, or macOS).
|
||||
* https://wiki.gnome.org/GitLab
|
||||
|
||||
The core dependencies for GTK are:
|
||||
|
||||
- [GLib, GObject, and GIO](https://gitlab.gnome.org/GNOME/glib)
|
||||
- [Cairo](http://cairographics.org)
|
||||
- [Pango](https://gitlab.gnome.org/GNOME/pango)
|
||||
- [GdkPixbuf](https://gitlab.gnome.org/GNOME/gdk-pixbuf)
|
||||
- [Epoxy](https://github.com/anholt/libepoxy)
|
||||
- [ATK](https://gitlab.gnome.org/GNOME/atk)
|
||||
- [Graphene](https://github.com/ebassi/graphene)
|
||||
|
||||
GTK will attempt to download and build some of these dependencies if it
|
||||
cannot find them on your system.
|
||||
|
||||
Additionally, you may want to look at projects that create a development
|
||||
environment for you, like [jhbuild](https://wiki.gnome.org/HowDoI/Jhbuild)
|
||||
and [gvsbuild](https://github.com/wingtk/gvsbuild).
|
||||
|
||||
### Getting started
|
||||
In order to get Git GTK+ installed on your system, you need to have the
|
||||
required versions of all the GTK+ dependencies; typically, this means a
|
||||
recent version of GLib, Cairo, Pango, and ATK, as well as the platform
|
||||
specific dependencies for the windowing system you are using (Wayland, X11,
|
||||
Windows, or macOS).
|
||||
|
||||
You should start by forking the GTK repository from the GitLab web UI, and
|
||||
cloning from your fork:
|
||||
|
||||
```sh
|
||||
```ssh
|
||||
$ git clone https://gitlab.gnome.org/yourusername/gtk.git
|
||||
$ cd gtk
|
||||
```
|
||||
@@ -151,7 +38,7 @@ $ git clone git@gitlab.gnome.org:GNOME/gtk.git
|
||||
$ cd gtk
|
||||
```
|
||||
|
||||
To compile the Git version of GTK on your system, you will need to
|
||||
To compile the Git version of GTK+ on your system, you will need to
|
||||
configure your build using Meson:
|
||||
|
||||
```sh
|
||||
@@ -160,6 +47,11 @@ $ cd _builddir
|
||||
$ ninja
|
||||
```
|
||||
|
||||
**Note**: For information about submitting patches and pushing changes
|
||||
to Git, see the `README.md` and `README.commits` files. In particular,
|
||||
don't, under any circumstances, push anything to Git before reading and
|
||||
understanding `README.commmits`.
|
||||
|
||||
Typically, you should work on your own branch:
|
||||
|
||||
```sh
|
||||
@@ -169,98 +61,3 @@ $ git checkout -b your-branch
|
||||
Once you've finished working on the bug fix or feature, push the branch
|
||||
to the Git repository and open a new merge request, to let the GTK
|
||||
maintainers review your contribution.
|
||||
|
||||
### Code reviews
|
||||
|
||||
Each contribution is reviewed by the core developers of the GTK project.
|
||||
|
||||
The [CODE-OWNERS](./docs/CODE-OWNERS) document contains the list of core
|
||||
contributors to GTK and the areas for which they are responsible; you
|
||||
should ensure to receive their review and signoff on your changes.
|
||||
|
||||
### Commit messages
|
||||
|
||||
The expected format for git commit messages is as follows:
|
||||
|
||||
```plain
|
||||
Short explanation of the commit
|
||||
|
||||
Longer explanation explaining exactly what's changed, whether any
|
||||
external or private interfaces changed, what bugs were fixed (with bug
|
||||
tracker reference if applicable) and so forth. Be concise but not too
|
||||
brief.
|
||||
|
||||
Closes #1234
|
||||
```
|
||||
|
||||
- Always add a brief description of the commit to the _first_ line of
|
||||
the commit and terminate by two newlines (it will work without the
|
||||
second newline, but that is not nice for the interfaces).
|
||||
|
||||
- First line (the brief description) must only be one sentence and
|
||||
should start with a capital letter unless it starts with a lowercase
|
||||
symbol or identifier. Don't use a trailing period either. Don't exceed
|
||||
72 characters.
|
||||
|
||||
- The main description (the body) is normal prose and should use normal
|
||||
punctuation and capital letters where appropriate. Consider the commit
|
||||
message as an email sent to the developers (or yourself, six months
|
||||
down the line) detailing **why** you changed something. There's no need
|
||||
to specify the **how**: the changes can be inlined.
|
||||
|
||||
- When committing code on behalf of others use the `--author` option, e.g.
|
||||
`git commit -a --author "Joe Coder <joe@coder.org>"` and `--signoff`.
|
||||
|
||||
- If your commit is addressing an issue, use the
|
||||
[GitLab syntax](https://docs.gitlab.com/ce/user/project/issues/automatic_issue_closing.html)
|
||||
to automatically close the issue when merging the commit with the upstream
|
||||
repository:
|
||||
|
||||
```plain
|
||||
Closes #1234
|
||||
Fixes #1234
|
||||
Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1234
|
||||
```
|
||||
|
||||
- If you have a merge request with multiple commits and none of them
|
||||
completely fixes an issue, you should add a reference to the issue in
|
||||
the commit message, e.g. `Bug: #1234`, and use the automatic issue
|
||||
closing syntax in the description of the merge request.
|
||||
|
||||
### Commit access to the GTK repository
|
||||
|
||||
GTK is part of the GNOME infrastructure. At the current time, any
|
||||
person with write access to the GNOME repository can merge changes to
|
||||
GTK. This is a good thing, in that it encourages many people to work
|
||||
on GTK, and progress can be made quickly. However, GTK is a fairly
|
||||
large and complicated project on which many other things depend, so to
|
||||
avoid unnecessary breakage, and to take advantage of the knowledge
|
||||
about GTK that has been built up over the years, we'd like to ask
|
||||
people committing to GTK to follow a few rules:
|
||||
|
||||
0. Ask first. If your changes are major, or could possibly break existing
|
||||
code, you should always ask. If your change is minor and you've been
|
||||
working on GTK for a while it probably isn't necessary to ask. But when
|
||||
in doubt, ask. Even if your change is correct, somebody may know a
|
||||
better way to do things. If you are making changes to GTK, you should
|
||||
be subscribed to the [gtk-devel](https://mail.gnome.org/mailman/listinfo/gtk-devel-list)
|
||||
mailing list; this is a good place to ask about intended changes.
|
||||
The `#gtk` IRC channel on irc.gnome.org is also a good place to find GTK
|
||||
developers to discuss changes, but if you live outside of the EU/US time
|
||||
zones, an email to the gtk-devel mailing list is the most certain and
|
||||
preferred method.
|
||||
|
||||
0. Ask _first_.
|
||||
|
||||
0. Always write a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted.
|
||||
|
||||
0. Never push to the `master` branch, or any stable branches, directly; you
|
||||
should always go through a merge request, to ensure that the code is
|
||||
tested on the CI infrastructure at the very least. A merge request is
|
||||
also the proper place to get a comprehensive code review from the core
|
||||
developers of GTK.
|
||||
|
||||
If you have been contributing to GTK for a while and you don't have commit
|
||||
access to the repository, you may ask to obtain it following the [GNOME account
|
||||
process](https://wiki.gnome.org/AccountsTeam/NewAccounts).
|
||||
|
190
NEWS
@@ -1,193 +1,3 @@
|
||||
Overview of Changes in GTK+ 3.96.0
|
||||
==================================
|
||||
|
||||
* DND has been refactored. There are now separate GdkDrag and GdkDrop
|
||||
objects. This work is still incomplete
|
||||
|
||||
* The GDK_SURFACE_SUBSURFACE surface type has been removed.
|
||||
|
||||
* Use of child surfaces has been greatly reduced. This work is still
|
||||
incomplete
|
||||
|
||||
* The use of global coordinates in GDK apis has been reduced. This
|
||||
work is still incomplete
|
||||
|
||||
* Events have been simplified and are used just for input
|
||||
- expose events have been replaced by a GdkSurface::render signal
|
||||
- configure events have been replaced by a GdkSurface::size-changed signal
|
||||
- map events have been replaced by a GdkSurface::mapped property
|
||||
- gdk_event_handler_set has been replaced by a GdkSurface::event signal
|
||||
- key events no longer contain a string
|
||||
- events on unmapped widgets are ignored
|
||||
|
||||
* Warping the pointer is no longer supported
|
||||
|
||||
* The Wayland backend now uses the Settings portal for GtkSettings
|
||||
|
||||
* The Wayland input module uses the text-input-unstable-v3 protocol
|
||||
|
||||
* The Broadway backend has been rewritten to work well with GSK
|
||||
|
||||
* The color chooser has a color picker
|
||||
|
||||
* GtkApplication tracks screensaver state and has a ::query-end signal
|
||||
|
||||
* The file chooser portal backend supports file filters
|
||||
|
||||
* A number of list models have been introduced, for internal use
|
||||
and as public api:
|
||||
- GtkMapListModel
|
||||
- GtkSliceListModel
|
||||
- GtkSortListModel
|
||||
- GtkSelectionModel
|
||||
- GtkSingleSelection
|
||||
|
||||
* Support for tabular menus and combo boxes has been dropped
|
||||
|
||||
* Key themes are no longer supported
|
||||
|
||||
* GtkInvisible has been dropped
|
||||
|
||||
* A GtkRoot interface has been added that is currently implemented
|
||||
just by GtkWindow. This work is incomplete
|
||||
|
||||
* GtkWidgets can transform their children using projective linear
|
||||
transformations. This functionality is available in CSS and
|
||||
as GskTransform argument to gtk_widget_allocate. GtkFixed is
|
||||
a container that exposes this functionality. For examples of this,
|
||||
see the swing transition of GtkRevealer, the rotate transitions
|
||||
of GtkStack or the Fixed Layout example in gtk-demo.
|
||||
|
||||
* GtkEntry functionality has been moved into a new GtkText widget,
|
||||
the GtkEditable interface has been expanded, and new a new
|
||||
GtkPasswordEntry widget has been introduced.
|
||||
|
||||
* Focus handling has been rewritten, and focus-change event
|
||||
generation has been unified with crossing events.
|
||||
|
||||
* All demos and settings schemas have been renamed to avoid collisions
|
||||
with GTK3.
|
||||
|
||||
* GtkWidget can now use a GtkLayoutManager for size allocation.
|
||||
Layout managers can optionally use layout children holding layout
|
||||
properties. A number of layout managers are available:
|
||||
- GtkBinLayout
|
||||
- GtkBoxLayout
|
||||
- GtkGridLayout
|
||||
- GtkFixedLayout
|
||||
- GtkCustomLayout
|
||||
More layout manager implementations will appear in the future.
|
||||
|
||||
* GtkAssistant, GtkStack and GtkNotebook now have publicly
|
||||
accessible page objects for their children. The page objects
|
||||
are also exposed via a list model.
|
||||
|
||||
* GtkContainer no longer supports child properties. All existing
|
||||
child properties have been removed, converted to regular properties,
|
||||
moved to layout properties or moved to child meta objects.
|
||||
|
||||
* GtkListBox has gained a ::show-separators property that gets
|
||||
translated into a CSS style class.
|
||||
|
||||
* A number of X11-specific GtkWindow and GdkSurface apis have been
|
||||
removed or changed to backend APIs.
|
||||
|
||||
* GtkBuilder can specify object-valued properties inline.
|
||||
|
||||
* The gtk4-builder-tool simplify command has gained a --3to4 option
|
||||
to convert GTK3 ui files to GTK4.
|
||||
|
||||
* The inspector can show child meta objects and layout properties.
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.94.0
|
||||
==================================
|
||||
|
||||
* GdkPaintable is a new, powerful abstraction for drawable content.
|
||||
gtk4-demo has a new "Paint" demo to show some of its capabilities.
|
||||
|
||||
* There is support for displaying media, with
|
||||
GtkVideo
|
||||
GtkMediaFile
|
||||
GtkMediaStream
|
||||
GtkMediaControls
|
||||
|
||||
* GtkFontChooser now supports OpenType font variations and features.
|
||||
|
||||
* The Ctrl-Shift-E support in the simple IM context has been replaced
|
||||
by an optional completion popup for Emoji alpha codes. This can be
|
||||
enabled with the GtkEntry::enable-emoji-completion property.
|
||||
|
||||
* Wayland has an input method based on the text protocol now
|
||||
|
||||
* Input methods, print backends and media backends have been converted
|
||||
to GIOModules and extension points, and support for generic loadable
|
||||
modules has been dropped. Platform im modules are always included.
|
||||
|
||||
* GdkWindow has been renamed to GdkSurface.
|
||||
|
||||
* Applications can now create their own GtkSnapshot objects for
|
||||
intermediate rendering.
|
||||
|
||||
* Widget event signals have been replaced by event controllers,
|
||||
and some new event controllers have been introduced for this:
|
||||
GtkEventControllerMotion
|
||||
GtkEventControllerKey
|
||||
GtkGestureStylus
|
||||
|
||||
* Event controllers can now be created in .ui files.
|
||||
|
||||
* Invalidation tracking has been changed, only gtk_widget_queue_draw is left.
|
||||
|
||||
* Observing widget contents and size is now done by using the
|
||||
GtkWidgetPaintable object instead of connecting to widget signals.
|
||||
|
||||
* The GtkWidget::draw signal has been removed, widgets need
|
||||
to implement GtkWidget::snapshot.
|
||||
|
||||
* GdkTexture now has GdkMemoryTexture and GdkGLTexture subclasses.
|
||||
|
||||
* The Vulkan support in GDK can now use a particular device that is
|
||||
specified by the GDK_VULKAN_DEVICE environment variable. use
|
||||
GDK_VULKAN_DEVICE=list to see them all.
|
||||
|
||||
* GTK+ Inspector
|
||||
- has logging support, and the logging settings have been cleaned up
|
||||
- has an fps overlay
|
||||
|
||||
* Removed APIs and features:
|
||||
Individual event signals such as ::proximity-in-event
|
||||
The ::draw signal
|
||||
threading support
|
||||
non-platform IM modules
|
||||
papi and test print backends
|
||||
GtkPlacesSidebar
|
||||
GtkRecentChooser
|
||||
GtkToolPalette
|
||||
GdkStatus
|
||||
gtk_true, gtk_false
|
||||
gtk_widget_show_now
|
||||
gtk_widget_draw
|
||||
gtk_render_icon_surface
|
||||
|
||||
* Incomplete transitions:
|
||||
The ::event signal is not still there, but it will be removed
|
||||
The DND apis are not finalized yet
|
||||
|
||||
* Translation updates:
|
||||
Croatian
|
||||
Esperanto
|
||||
Estonian
|
||||
French
|
||||
Friulian
|
||||
Icelandic
|
||||
Latvian
|
||||
Polish
|
||||
Russian
|
||||
Scottish Gaelic
|
||||
Spanish
|
||||
|
||||
|
||||
Overview of Changes in GTK+ 3.93.0
|
||||
==================================
|
||||
|
||||
|
72
README.commits
Normal file
@@ -0,0 +1,72 @@
|
||||
GTK+ is part of the GNOME git repository. At the current time, any
|
||||
person with write access to the GNOME repository, can make changes to
|
||||
GTK+. This is a good thing, in that it encourages many people to work
|
||||
on GTK+, and progress can be made quickly. However, GTK+ is a fairly
|
||||
large and complicated package that many other things depend on, so to
|
||||
avoid unnecessary breakage, and to take advantage of the knowledge
|
||||
about GTK+ that has been built up over the years, we'd like to ask
|
||||
people committing to GTK+ to follow a few rules:
|
||||
|
||||
0) Ask first. If your changes are major, or could possibly break existing
|
||||
code, you should always ask. If your change is minor and you've
|
||||
been working on GTK+ for a while it probably isn't necessary
|
||||
to ask. But when in doubt, ask. Even if your change is correct,
|
||||
somebody may know a better way to do things.
|
||||
|
||||
If you are making changes to GTK+, you should be subscribed
|
||||
to gtk-devel-list@gnome.org. (Subscription address:
|
||||
gtk-devel-list-request@gnome.org.) This is a good place to ask
|
||||
about intended changes.
|
||||
|
||||
#gtk+ on GIMPNet (irc.gimp.org, irc.us.gimp.org, irc.eu.gimp.org, ...)
|
||||
is also a good place to find GTK+ developers to discuss changes with,
|
||||
however, email to gtk-devel-list is the most certain and preferred
|
||||
method.
|
||||
|
||||
1) Ask _first_.
|
||||
|
||||
2) With git, we no longer maintain a ChangeLog file, but you are expected
|
||||
to produce a meaningful commit message. Changes without a sufficient
|
||||
commit message will be reverted. See below for the expected format
|
||||
of commit messages.
|
||||
|
||||
Notes:
|
||||
|
||||
* When developing larger features or complicated bug fixes, it is
|
||||
advisable to work in a branch in your own cloned GTK+ repository.
|
||||
You may even consider making your repository publically available
|
||||
so that others can easily test and review your changes.
|
||||
|
||||
* The expected format for git commit messages is as follows:
|
||||
|
||||
=== begin example commit ===
|
||||
Short explanation of the commit
|
||||
|
||||
Longer explanation explaining exactly what's changed, whether any
|
||||
external or private interfaces changed, what bugs were fixed (with bug
|
||||
tracker reference if applicable) and so forth. Be concise but not too brief.
|
||||
=== end example commit ===
|
||||
|
||||
- Always add a brief description of the commit to the _first_ line of
|
||||
the commit and terminate by two newlines (it will work without the
|
||||
second newline, but that is not nice for the interfaces).
|
||||
|
||||
- First line (the brief description) must only be one sentence and
|
||||
should start with a capital letter unless it starts with a lowercase
|
||||
symbol or identifier. Don't use a trailing period either. Don't exceed
|
||||
72 characters.
|
||||
|
||||
- The main description (the body) is normal prose and should use normal
|
||||
punctuation and capital letters where appropriate. Normally, for patches
|
||||
sent to a mailing list it's copied from there.
|
||||
|
||||
- When committing code on behalf of others use the --author option, e.g.
|
||||
git commit -a --author "Joe Coder <joe@coder.org>" and --signoff.
|
||||
|
||||
|
||||
Owen Taylor
|
||||
13 Aug 1998
|
||||
17 Apr 2001
|
||||
|
||||
Matthias Clasen
|
||||
31 Mar 2009
|
31
README.md
@@ -1,17 +1,17 @@
|
||||
GTK — The GTK toolkit
|
||||
=====================
|
||||
GTK+ — The GTK toolkit
|
||||
======================
|
||||
|
||||
[](https://gitlab.gnome.org/GNOME/gtk/pipelines)
|
||||
|
||||
General information
|
||||
-------------------
|
||||
|
||||
GTK is a multi-platform toolkit for creating graphical user interfaces.
|
||||
Offering a complete set of widgets, GTK is suitable for projects ranging
|
||||
GTK+ is a multi-platform toolkit for creating graphical user interfaces.
|
||||
Offering a complete set of widgets, GTK+ is suitable for projects ranging
|
||||
from small one-off projects to complete application suites.
|
||||
|
||||
GTK is free software and part of the GNU Project. However, the
|
||||
licensing terms for GTK, the GNU LGPL, allow it to be used by all
|
||||
GTK+ is free software and part of the GNU Project. However, the
|
||||
licensing terms for GTK+, the GNU LGPL, allow it to be used by all
|
||||
developers, including those developing proprietary software, without any
|
||||
license fees or royalties.
|
||||
|
||||
@@ -31,15 +31,10 @@ Information about mailing lists can be found at
|
||||
|
||||
- http://www.gtk.org/mailing-lists.php
|
||||
|
||||
Nightly documentation can be found at
|
||||
- Gtk: https://gnome.pages.gitlab.gnome.org/gtk/gtk/
|
||||
- Gdk: https://gnome.pages.gitlab.gnome.org/gtk/gdk/
|
||||
- Gsk: https://gnome.pages.gitlab.gnome.org/gtk/gsk/
|
||||
|
||||
Building and installing
|
||||
-----------------------
|
||||
|
||||
In order to build GTK you will need:
|
||||
In order to build GTK+ you will need:
|
||||
|
||||
- [a C99 compatible compiler](https://wiki.gnome.org/Projects/GLib/CompilerRequirements)
|
||||
- [Python 3](https://www.python.org/)
|
||||
@@ -79,7 +74,7 @@ If you are building the Wayland backend, you will also need:
|
||||
- Wayland-cursor
|
||||
- Wayland-EGL
|
||||
|
||||
Once you have all the necessary dependencies, you can build GTK by using
|
||||
Once you have all the necessary dependencies, you can build GTK+ by using
|
||||
Meson:
|
||||
|
||||
```sh
|
||||
@@ -94,7 +89,7 @@ You can run the test suite using:
|
||||
$ meson test
|
||||
```
|
||||
|
||||
And, finally, you can install GTK using:
|
||||
And, finally, you can install GTK+ using:
|
||||
|
||||
```
|
||||
$ sudo ninja install
|
||||
@@ -118,10 +113,10 @@ In the bug report please include:
|
||||
|
||||
* Information about your system. For instance:
|
||||
|
||||
- which version of GTK you are using
|
||||
- which version of GTK+ you are using
|
||||
- what operating system and version
|
||||
- for Linux, which distribution
|
||||
- if you built GTK, the list of options used to configure the build
|
||||
- if you built GTK+, the list of options used to configure the build
|
||||
|
||||
And anything else you think is relevant.
|
||||
|
||||
@@ -143,7 +138,7 @@ In the bug report please include:
|
||||
Release notes
|
||||
-------------
|
||||
|
||||
The release notes for GTK are part of the migration guide in the API
|
||||
The release notes for GTK+ are part of the migration guide in the API
|
||||
reference. See:
|
||||
|
||||
- [3.x release notes](https://developer.gnome.org/gtk3/unstable/gtk-migrating-2-to-3.html)
|
||||
@@ -152,7 +147,7 @@ reference. See:
|
||||
Licensing terms
|
||||
---------------
|
||||
|
||||
GTK is released under the terms of the GNU Lesser General Public License,
|
||||
GTK+ is released under the terms of the GNU Lesser General Public License,
|
||||
version 2.1 or, at your option, any later version, as published by the Free
|
||||
Software Foundation.
|
||||
|
||||
|
@@ -1,17 +1,20 @@
|
||||
{
|
||||
"app-id": "org.gtk.Demo4",
|
||||
"app-id": "org.gtk.Demo",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-demo",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-demo.desktop",
|
||||
"rename-icon": "gtk4-demo",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*",
|
||||
"--talk-name=ca.desrt.conf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
@@ -24,28 +27,12 @@
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--disable-documentation"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/wayland-project/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources": [
|
||||
{
|
@@ -1,72 +0,0 @@
|
||||
{
|
||||
"app-id": "org.gtk.IconBrowser4",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-icon-browser",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
"/lib/pkgconfig", "/share/pkgconfig",
|
||||
"/share/aclocal",
|
||||
"/man", "/share/man", "/share/gtk-doc",
|
||||
"*.la", ".a",
|
||||
"/lib/girepository-1.0",
|
||||
"/share/gir-1.0",
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--disable-documentation"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/wayland-project/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/ebassi/graphene.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "gtk",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://gitlab.gnome.org/GNOME/gtk.git"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@@ -1,17 +1,20 @@
|
||||
{
|
||||
"app-id": "org.gtk.WidgetFactory4",
|
||||
"app-id": "org.gtk.WidgetFactory",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "gtk4-widget-factory",
|
||||
"tags": ["devel", "development", "nightly"],
|
||||
"rename-desktop-file": "gtk4-widget-factory.desktop",
|
||||
"rename-icon": "gtk4-widget-factory",
|
||||
"desktop-file-name-prefix": "(Development) ",
|
||||
"finish-args": [
|
||||
"--device=dri",
|
||||
"--share=ipc",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=x11",
|
||||
"--socket=wayland",
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*"
|
||||
"--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*",
|
||||
"--talk-name=ca.desrt.conf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf"
|
||||
],
|
||||
"cleanup": [
|
||||
"/include",
|
||||
@@ -24,28 +27,12 @@
|
||||
"/share/doc"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name" : "wayland",
|
||||
"buildsystem" : "autotools",
|
||||
"builddir" : true,
|
||||
"config-opts" : [
|
||||
"--disable-documentation"
|
||||
],
|
||||
"sources" : [
|
||||
{
|
||||
"type" : "git",
|
||||
"url" : "https://github.com/wayland-project/wayland.git"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "graphene",
|
||||
"buildsystem": "meson",
|
||||
"builddir": true,
|
||||
"config-opts": [
|
||||
"--libdir=/app/lib",
|
||||
"-Dtests=false",
|
||||
"-Dbenchmarks=false"
|
||||
"--libdir=/app/lib"
|
||||
],
|
||||
"sources": [
|
||||
{
|
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
if 'DESTDIR' not in os.environ:
|
||||
gtk_api_version = sys.argv[1]
|
||||
gtk_abi_version = sys.argv[2]
|
||||
gtk_libdir = sys.argv[3]
|
||||
gtk_datadir = sys.argv[4]
|
||||
|
||||
gtk_moduledir = os.path.join(gtk_libdir, 'gtk-' + gtk_api_version, gtk_abi_version)
|
||||
gtk_printmodule_dir = os.path.join(gtk_moduledir, 'printbackends')
|
||||
gtk_immodule_dir = os.path.join(gtk_moduledir, 'immodules')
|
||||
|
||||
print('Compiling GSettings schemas...')
|
||||
subprocess.call(['glib-compile-schemas',
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
subprocess.call(['gtk4-update-icon-cache', '-q', '-t' ,'-f',
|
||||
os.path.join(gtk_datadir, 'icons', 'hicolor')])
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
os.makedirs(gtk_printmodule_dir, exist_ok=True)
|
||||
subprocess.call(['gio-querymodules', gtk_printmodule_dir])
|
||||
|
||||
print('Updating module cache for input methods...')
|
||||
os.makedirs(gtk_immodule_dir, exist_ok=True)
|
||||
subprocess.call(['gio-querymodules', gtk_immodule_dir])
|
26
build-aux/meson/post-install.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
gtk_api_version=$1
|
||||
gtk_abi_version=$2
|
||||
gtk_libdir=$3
|
||||
gtk_datadir=$4
|
||||
|
||||
# Package managers set this so we don't need to run
|
||||
if [ -z "$DESTDIR" ]; then
|
||||
echo Compiling GSettings schemas...
|
||||
glib-compile-schemas ${gtk_datadir}/glib-2.0/schemas
|
||||
|
||||
echo Updating desktop database...
|
||||
update-desktop-database -q ${gtk_datadir}/applications
|
||||
|
||||
echo Updating icon cache...
|
||||
gtk-update-icon-cache -q -t -f ${gtk_datadir}/icons/hicolor
|
||||
|
||||
echo Updating module cache for print backends...
|
||||
mkdir -p ${gtk_libdir}/gtk-4.0/4.0.0/printbackends
|
||||
gio-querymodules ${gtk_libdir}/gtk-4.0/4.0.0/printbackends
|
||||
|
||||
echo Updating module cache for input methods...
|
||||
mkdir -p ${gtk_libdir}/gtk-4.0/4.0.0/immodules
|
||||
gio-querymodules ${gtk_libdir}/gtk-4.0/4.0.0/immodules
|
||||
fi
|
@@ -24,6 +24,9 @@
|
||||
/* Define to 1 if you have the <crt_externs.h> header file. */
|
||||
#mesondefine HAVE_CRT_EXTERNS_H
|
||||
|
||||
/* Define to 1 if CUPS 1.6 API is available */
|
||||
#mesondefine HAVE_CUPS_API_1_6
|
||||
|
||||
/* Define to 1 if you have the `dcgettext' function. */
|
||||
#mesondefine HAVE_DCGETTEXT
|
||||
|
||||
@@ -131,9 +134,6 @@
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#mesondefine HAVE_SYS_PARAM_H
|
||||
|
||||
/* Have the sysprof-capture library */
|
||||
#mesondefine HAVE_SYSPROF_CAPTURE
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#mesondefine HAVE_SYS_STAT_H
|
||||
|
||||
@@ -244,6 +244,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 if XInput 2.0 is available */
|
||||
#mesondefine XINPUT_2
|
||||
|
||||
/* Define to 1 if XInput 2.2 is available */
|
||||
#mesondefine XINPUT_2_2
|
||||
|
||||
@@ -283,10 +286,6 @@
|
||||
/* Define to 1 if linux/memfd.h exists */
|
||||
#mesondefine HAVE_LINUX_MEMFD_H
|
||||
|
||||
#mesondefine HAVE_LINUX_INPUT_H
|
||||
|
||||
#mesondefine HAVE_DEV_EVDEV_INPUT_H
|
||||
|
||||
#mesondefine GTK_SYSCONFDIR
|
||||
|
||||
#mesondefine GTK_LOCALEDIR
|
||||
@@ -297,8 +296,6 @@
|
||||
|
||||
#mesondefine GTK_PRINT_BACKENDS
|
||||
|
||||
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
|
||||
|
||||
#mesondefine HAVE_HARFBUZZ
|
||||
|
||||
#mesondefine HAVE_PANGOFT
|
||||
|
@@ -200,20 +200,20 @@ activate_about (GSimpleAction *action,
|
||||
};
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (window),
|
||||
"program-name", "GTK Code Demos",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK %d.%d.%d",
|
||||
"program-name", "GTK+ Code Demos",
|
||||
"version", g_strdup_printf ("%s,\nRunning against GTK+ %d.%d.%d",
|
||||
PACKAGE_VERSION,
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ()),
|
||||
"copyright", "(C) 1997-2013 The GTK Team",
|
||||
"copyright", "(C) 1997-2013 The GTK+ Team",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK functions.",
|
||||
"comments", "Program to demonstrate GTK+ functions.",
|
||||
"authors", authors,
|
||||
"documenters", documentors,
|
||||
"logo-icon-name", "org.gtk.Demo4",
|
||||
"title", "About GTK Code Demos",
|
||||
"logo-icon-name", "gtk4-demo",
|
||||
"title", "About GTK+ Code Demos",
|
||||
NULL);
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ demo_application_init (DemoApplication *app)
|
||||
GSettings *settings;
|
||||
GAction *action;
|
||||
|
||||
settings = g_settings_new ("org.gtk.Demo4");
|
||||
settings = g_settings_new ("org.gtk.Demo");
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
@@ -397,7 +397,7 @@ demo_application_window_store_state (DemoApplicationWindow *win)
|
||||
{
|
||||
GSettings *settings;
|
||||
|
||||
settings = g_settings_new ("org.gtk.Demo4");
|
||||
settings = g_settings_new ("org.gtk.Demo");
|
||||
g_settings_set (settings, "window-size", "(ii)", win->width, win->height);
|
||||
g_settings_set_boolean (settings, "maximized", win->maximized);
|
||||
g_settings_set_boolean (settings, "fullscreen", win->fullscreen);
|
||||
@@ -409,7 +409,7 @@ demo_application_window_load_state (DemoApplicationWindow *win)
|
||||
{
|
||||
GSettings *settings;
|
||||
|
||||
settings = g_settings_new ("org.gtk.Demo4");
|
||||
settings = g_settings_new ("org.gtk.Demo");
|
||||
g_settings_get (settings, "window-size", "(ii)", &win->width, &win->height);
|
||||
win->maximized = g_settings_get_boolean (settings, "maximized");
|
||||
win->fullscreen = g_settings_get_boolean (settings, "fullscreen");
|
||||
@@ -455,17 +455,15 @@ demo_application_window_constructed (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
demo_application_window_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
demo_application_window_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget,
|
||||
width,
|
||||
height,
|
||||
baseline);
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->size_allocate (widget, allocation,
|
||||
baseline, out_clip);
|
||||
|
||||
if (!window->maximized && !window->fullscreen)
|
||||
gtk_window_get_size (GTK_WINDOW (window), &window->width, &window->height);
|
||||
@@ -477,7 +475,7 @@ surface_state_changed (GtkWidget *widget)
|
||||
DemoApplicationWindow *window = (DemoApplicationWindow *)widget;
|
||||
GdkSurfaceState new_state;
|
||||
|
||||
new_state = gdk_surface_get_state (gtk_native_get_surface (GTK_NATIVE (widget)));
|
||||
new_state = gdk_surface_get_state (gtk_widget_get_surface (widget));
|
||||
window->maximized = (new_state & GDK_SURFACE_STATE_MAXIMIZED) != 0;
|
||||
window->fullscreen = (new_state & GDK_SURFACE_STATE_FULLSCREEN) != 0;
|
||||
}
|
||||
@@ -487,14 +485,14 @@ demo_application_window_realize (GtkWidget *widget)
|
||||
{
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->realize (widget);
|
||||
|
||||
g_signal_connect_swapped (gtk_native_get_surface (GTK_NATIVE (widget)), "notify::state",
|
||||
g_signal_connect_swapped (gtk_widget_get_surface (widget), "notify::state",
|
||||
G_CALLBACK (surface_state_changed), widget);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_application_window_unrealize (GtkWidget *widget)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (gtk_native_get_surface (GTK_NATIVE (widget)),
|
||||
g_signal_handlers_disconnect_by_func (gtk_widget_get_surface (widget),
|
||||
surface_state_changed, widget);
|
||||
|
||||
GTK_WIDGET_CLASS (demo_application_window_parent_class)->unrealize (widget);
|
||||
@@ -541,7 +539,7 @@ main (int argc, char *argv[])
|
||||
GtkApplication *app;
|
||||
|
||||
app = GTK_APPLICATION (g_object_new (demo_application_get_type (),
|
||||
"application-id", "org.gtk.Demo4.App",
|
||||
"application-id", "org.gtk.Demo2",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL));
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<template class="DemoApplicationWindow" parent="GtkApplicationWindow">
|
||||
<property name="title" translatable="yes">Application Class</property>
|
||||
@@ -25,7 +25,8 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem"/>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
@@ -33,11 +34,11 @@
|
||||
<property name="action-name">win.logo</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="infobar">
|
||||
@@ -64,11 +65,11 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
@@ -80,20 +81,20 @@
|
||||
<property name="buffer">buffer</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="status">
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
@@ -52,7 +52,7 @@ do_application_demo (GtkWidget *toplevel)
|
||||
|
||||
if (watch == 0)
|
||||
watch = g_bus_watch_name (G_BUS_TYPE_SESSION,
|
||||
"org.gtk.Demo4.App",
|
||||
"org.gtk.Demo2",
|
||||
0,
|
||||
on_name_appeared,
|
||||
on_name_vanished,
|
||||
@@ -80,8 +80,8 @@ do_application_demo (GtkWidget *toplevel)
|
||||
else
|
||||
{
|
||||
g_dbus_connection_call_sync (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
|
||||
"org.gtk.Demo4.App",
|
||||
"/org/gtk/Demo4/App",
|
||||
"org.gtk.Demo2",
|
||||
"/org/gtk/Demo2",
|
||||
"org.gtk.Actions",
|
||||
"Activate",
|
||||
g_variant_new ("(sava{sv})", "quit", NULL, NULL),
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.10 -->
|
||||
<menu id="appmenu">
|
||||
<section>
|
||||
<item>
|
||||
|
@@ -80,7 +80,7 @@ on_entry_changed (GtkWidget *widget, gpointer data)
|
||||
|
||||
page_number = gtk_assistant_get_current_page (assistant);
|
||||
current_page = gtk_assistant_get_nth_page (assistant, page_number);
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (widget));
|
||||
text = gtk_entry_get_text (GTK_ENTRY (widget));
|
||||
|
||||
if (text && *text)
|
||||
gtk_assistant_set_page_complete (assistant, current_page, TRUE);
|
||||
@@ -96,12 +96,12 @@ create_page1 (GtkWidget *assistant)
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
|
||||
label = gtk_label_new ("You must fill out this entry to continue:");
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
gtk_box_pack_start (GTK_BOX (box), label);
|
||||
|
||||
entry = gtk_entry_new ();
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
||||
gtk_widget_set_valign (entry, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (box), entry);
|
||||
gtk_box_pack_start (GTK_BOX (box), entry);
|
||||
g_signal_connect (G_OBJECT (entry), "changed",
|
||||
G_CALLBACK (on_entry_changed), assistant);
|
||||
|
||||
@@ -119,7 +119,7 @@ create_page2 (GtkWidget *assistant)
|
||||
|
||||
checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
|
||||
"even if you do not check this");
|
||||
gtk_container_add (GTK_CONTAINER (box), checkbutton);
|
||||
gtk_box_pack_start (GTK_BOX (box), checkbutton);
|
||||
|
||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
|
||||
gtk_assistant_set_page_complete (GTK_ASSISTANT (assistant), box, TRUE);
|
||||
|
@@ -17,11 +17,11 @@
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow">
|
||||
@@ -29,22 +29,22 @@
|
||||
<property name="vexpand">1</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="min-content-width">150</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackSwitcher">
|
||||
<property name="halign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="stack">stack</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
@@ -54,284 +54,279 @@
|
||||
<property name="vhomogeneous">0</property>
|
||||
<property name="transition-type">crossfade</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Duck</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Background</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="duck"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="gradient"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">
|
||||
Blended picture</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">center</property>
|
||||
<style>
|
||||
<class name="blend0"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page0</property>
|
||||
<property name="title" translatable="yes">Ducky</property>
|
||||
<property name="child">
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Duck</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Background</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="duck"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="gradient"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">
|
||||
Blended picture</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">center</property>
|
||||
<style>
|
||||
<class name="blend0"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Red</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Blue</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="red"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="blue"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">
|
||||
Blended picture</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">center</property>
|
||||
<style>
|
||||
<class name="blend1"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page1</property>
|
||||
<property name="title" translatable="yes">Blends</property>
|
||||
<property name="child">
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="row-spacing">12</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Red</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Blue</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="red"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="blue"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">
|
||||
Blended picture</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">center</property>
|
||||
<style>
|
||||
<class name="blend1"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="cyan"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="magenta"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="yellow"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">center</property>
|
||||
<style>
|
||||
<class name="blend2"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Cyan</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Magenta</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Yellow</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Blended picture</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">page2</property>
|
||||
<property name="title" translatable="yes">CMYK</property>
|
||||
<property name="child">
|
||||
<object class="GtkGrid">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<property name="row-spacing">6</property>
|
||||
<property name="column-spacing">12</property>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="cyan"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="magenta"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<style>
|
||||
<class name="yellow"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="halign">center</property>
|
||||
<style>
|
||||
<class name="blend2"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Cyan</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Magenta</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Yellow</property>
|
||||
<property name="xalign">0</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" translatable="yes">Blended picture</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</packing>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar"/>
|
||||
<child type="titlebar">
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
@@ -1,481 +0,0 @@
|
||||
/*
|
||||
* bluroverlay.c
|
||||
* This file is part of gtk
|
||||
*
|
||||
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "bluroverlay.h"
|
||||
|
||||
/*
|
||||
* This is a cut-down copy of gtkoverlay.c with a custom snapshot
|
||||
* function that support a limited form of blur-under.
|
||||
*/
|
||||
typedef struct _BlurOverlayChild BlurOverlayChild;
|
||||
|
||||
struct _BlurOverlayChild
|
||||
{
|
||||
double blur;
|
||||
};
|
||||
|
||||
enum {
|
||||
GET_CHILD_POSITION,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
static GQuark child_data_quark = 0;
|
||||
|
||||
G_DEFINE_TYPE (BlurOverlay, blur_overlay, GTK_TYPE_BIN)
|
||||
|
||||
static void
|
||||
blur_overlay_set_overlay_child (GtkWidget *widget,
|
||||
BlurOverlayChild *child_data)
|
||||
{
|
||||
g_object_set_qdata_full (G_OBJECT (widget), child_data_quark, child_data, g_free);
|
||||
}
|
||||
|
||||
static BlurOverlayChild *
|
||||
blur_overlay_get_overlay_child (GtkWidget *widget)
|
||||
{
|
||||
return (BlurOverlayChild *) g_object_get_qdata (G_OBJECT (widget), child_data_quark);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
int child_min, child_nat, child_min_baseline, child_nat_baseline;
|
||||
|
||||
gtk_widget_measure (child,
|
||||
orientation,
|
||||
for_size,
|
||||
&child_min, &child_nat,
|
||||
&child_min_baseline, &child_nat_baseline);
|
||||
|
||||
*minimum = MAX (*minimum, child_min);
|
||||
*natural = MAX (*natural, child_nat);
|
||||
if (child_min_baseline > -1)
|
||||
*minimum_baseline = MAX (*minimum_baseline, child_min_baseline);
|
||||
if (child_nat_baseline > -1)
|
||||
*natural_baseline = MAX (*natural_baseline, child_nat_baseline);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_compute_child_allocation (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
BlurOverlayChild *child,
|
||||
GtkAllocation *widget_allocation)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
gboolean result;
|
||||
|
||||
g_signal_emit (overlay, signals[GET_CHILD_POSITION],
|
||||
0, widget, &allocation, &result);
|
||||
|
||||
widget_allocation->x = allocation.x;
|
||||
widget_allocation->y = allocation.y;
|
||||
widget_allocation->width = allocation.width;
|
||||
widget_allocation->height = allocation.height;
|
||||
}
|
||||
|
||||
static GtkAlign
|
||||
effective_align (GtkAlign align,
|
||||
GtkTextDirection direction)
|
||||
{
|
||||
switch (align)
|
||||
{
|
||||
case GTK_ALIGN_START:
|
||||
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_END : GTK_ALIGN_START;
|
||||
case GTK_ALIGN_END:
|
||||
return direction == GTK_TEXT_DIR_RTL ? GTK_ALIGN_START : GTK_ALIGN_END;
|
||||
case GTK_ALIGN_FILL:
|
||||
case GTK_ALIGN_CENTER:
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
return align;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_child_update_style_classes (BlurOverlay *overlay,
|
||||
GtkWidget *child,
|
||||
GtkAllocation *child_allocation)
|
||||
{
|
||||
int width, height;
|
||||
GtkAlign valign, halign;
|
||||
gboolean is_left, is_right, is_top, is_bottom;
|
||||
gboolean has_left, has_right, has_top, has_bottom;
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (child);
|
||||
has_left = gtk_style_context_has_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
has_right = gtk_style_context_has_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
has_top = gtk_style_context_has_class (context, GTK_STYLE_CLASS_TOP);
|
||||
has_bottom = gtk_style_context_has_class (context, GTK_STYLE_CLASS_BOTTOM);
|
||||
|
||||
is_left = is_right = is_top = is_bottom = FALSE;
|
||||
|
||||
width = gtk_widget_get_width (GTK_WIDGET (overlay));
|
||||
height = gtk_widget_get_height (GTK_WIDGET (overlay));
|
||||
|
||||
halign = effective_align (gtk_widget_get_halign (child),
|
||||
gtk_widget_get_direction (child));
|
||||
|
||||
if (halign == GTK_ALIGN_START)
|
||||
is_left = (child_allocation->x == 0);
|
||||
else if (halign == GTK_ALIGN_END)
|
||||
is_right = (child_allocation->x + child_allocation->width == width);
|
||||
|
||||
valign = gtk_widget_get_valign (child);
|
||||
|
||||
if (valign == GTK_ALIGN_START)
|
||||
is_top = (child_allocation->y == 0);
|
||||
else if (valign == GTK_ALIGN_END)
|
||||
is_bottom = (child_allocation->y + child_allocation->height == height);
|
||||
|
||||
if (has_left && !is_left)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
else if (!has_left && is_left)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_LEFT);
|
||||
|
||||
if (has_right && !is_right)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
else if (!has_right && is_right)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RIGHT);
|
||||
|
||||
if (has_top && !is_top)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_TOP);
|
||||
else if (!has_top && is_top)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_TOP);
|
||||
|
||||
if (has_bottom && !is_bottom)
|
||||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_BOTTOM);
|
||||
else if (!has_bottom && is_bottom)
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_BOTTOM);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_child_allocate (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
BlurOverlayChild *child)
|
||||
{
|
||||
GtkAllocation child_allocation;
|
||||
|
||||
if (!gtk_widget_get_visible (widget))
|
||||
return;
|
||||
|
||||
blur_overlay_compute_child_allocation (overlay, widget, child, &child_allocation);
|
||||
|
||||
blur_overlay_child_update_style_classes (overlay, widget, &child_allocation);
|
||||
gtk_widget_size_allocate (widget, &child_allocation, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (widget);
|
||||
GtkWidget *child;
|
||||
GtkWidget *main_widget;
|
||||
|
||||
main_widget = gtk_bin_get_child (GTK_BIN (overlay));
|
||||
if (main_widget && gtk_widget_get_visible (main_widget))
|
||||
gtk_widget_size_allocate (main_widget,
|
||||
&(GtkAllocation) {
|
||||
0, 0,
|
||||
width, height
|
||||
}, -1);
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (child != main_widget)
|
||||
{
|
||||
BlurOverlayChild *child_data = blur_overlay_get_overlay_child (child);
|
||||
blur_overlay_child_allocate (overlay, child, child_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
blur_overlay_get_child_position (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
GtkAllocation *alloc)
|
||||
{
|
||||
GtkRequisition min, req;
|
||||
GtkAlign halign;
|
||||
GtkTextDirection direction;
|
||||
int width, height;
|
||||
|
||||
gtk_widget_get_preferred_size (widget, &min, &req);
|
||||
width = gtk_widget_get_width (GTK_WIDGET (overlay));
|
||||
height = gtk_widget_get_height (GTK_WIDGET (overlay));
|
||||
|
||||
alloc->x = 0;
|
||||
alloc->width = MAX (min.width, MIN (width, req.width));
|
||||
|
||||
direction = gtk_widget_get_direction (widget);
|
||||
|
||||
halign = gtk_widget_get_halign (widget);
|
||||
switch (effective_align (halign, direction))
|
||||
{
|
||||
case GTK_ALIGN_START:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case GTK_ALIGN_FILL:
|
||||
alloc->width = MAX (alloc->width, width);
|
||||
break;
|
||||
case GTK_ALIGN_CENTER:
|
||||
alloc->x += width / 2 - alloc->width / 2;
|
||||
break;
|
||||
case GTK_ALIGN_END:
|
||||
alloc->x += width - alloc->width;
|
||||
break;
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
alloc->y = 0;
|
||||
alloc->height = MAX (min.height, MIN (height, req.height));
|
||||
|
||||
switch (gtk_widget_get_valign (widget))
|
||||
{
|
||||
case GTK_ALIGN_START:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case GTK_ALIGN_FILL:
|
||||
alloc->height = MAX (alloc->height, height);
|
||||
break;
|
||||
case GTK_ALIGN_CENTER:
|
||||
alloc->y += height / 2 - alloc->height / 2;
|
||||
break;
|
||||
case GTK_ALIGN_END:
|
||||
alloc->y += height - alloc->height;
|
||||
break;
|
||||
case GTK_ALIGN_BASELINE:
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_add (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (container);
|
||||
gtk_widget_insert_after (widget, GTK_WIDGET (container), NULL);
|
||||
overlay->main_widget = widget;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_remove (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
BlurOverlay *overlay = BLUR_OVERLAY (container);
|
||||
gtk_widget_unparent (widget);
|
||||
if (overlay->main_widget == widget)
|
||||
overlay->main_widget = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_forall (GtkContainer *overlay,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
child = gtk_widget_get_first_child (GTK_WIDGET (overlay));
|
||||
while (child != NULL)
|
||||
{
|
||||
GtkWidget *next = gtk_widget_get_next_sibling (child);
|
||||
|
||||
(* callback) (child, callback_data);
|
||||
|
||||
child = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
GtkWidget *main_widget;
|
||||
GskRenderNode *main_widget_node = NULL;
|
||||
GtkWidget *child;
|
||||
GtkAllocation main_alloc;
|
||||
cairo_region_t *clip = NULL;
|
||||
int i;
|
||||
|
||||
main_widget = BLUR_OVERLAY (widget)->main_widget;
|
||||
gtk_widget_get_allocation (widget, &main_alloc);
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
BlurOverlayChild *child_info = blur_overlay_get_overlay_child (child);
|
||||
double blur = 0;
|
||||
if (child_info)
|
||||
blur = child_info->blur;
|
||||
|
||||
if (blur > 0)
|
||||
{
|
||||
GtkAllocation alloc;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
if (main_widget_node == NULL)
|
||||
{
|
||||
GtkSnapshot *child_snapshot;
|
||||
|
||||
child_snapshot = gtk_snapshot_new ();
|
||||
gtk_widget_snapshot_child (widget, main_widget, child_snapshot);
|
||||
main_widget_node = gtk_snapshot_free_to_node (child_snapshot);
|
||||
}
|
||||
|
||||
gtk_widget_get_allocation (child, &alloc);
|
||||
graphene_rect_init (&bounds, alloc.x, alloc.y, alloc.width, alloc.height);
|
||||
gtk_snapshot_push_blur (snapshot, blur);
|
||||
gtk_snapshot_push_clip (snapshot, &bounds);
|
||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
|
||||
if (clip == NULL)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = main_alloc.width;
|
||||
rect.height = main_alloc.height;
|
||||
clip = cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
cairo_region_subtract_rectangle (clip, (cairo_rectangle_int_t *)&alloc);
|
||||
}
|
||||
}
|
||||
|
||||
if (clip == NULL)
|
||||
{
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
gtk_widget_snapshot_child (widget, child, snapshot);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < cairo_region_num_rectangles (clip); i++)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
graphene_rect_t bounds;
|
||||
|
||||
cairo_region_get_rectangle (clip, i, &rect);
|
||||
graphene_rect_init (&bounds, rect.x, rect.y, rect.width, rect.height);
|
||||
gtk_snapshot_push_clip (snapshot, &bounds);
|
||||
gtk_snapshot_append_node (snapshot, main_widget_node);
|
||||
gtk_snapshot_pop (snapshot);
|
||||
}
|
||||
|
||||
cairo_region_destroy (clip);
|
||||
|
||||
for (child = gtk_widget_get_first_child (widget);
|
||||
child != NULL;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (child != main_widget)
|
||||
gtk_widget_snapshot_child (widget, child, snapshot);
|
||||
}
|
||||
|
||||
gsk_render_node_unref (main_widget_node);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_class_init (BlurOverlayClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
widget_class->measure = blur_overlay_measure;
|
||||
widget_class->size_allocate = blur_overlay_size_allocate;
|
||||
widget_class->snapshot = blur_overlay_snapshot;
|
||||
|
||||
container_class->add = blur_overlay_add;
|
||||
container_class->remove = blur_overlay_remove;
|
||||
container_class->forall = blur_overlay_forall;
|
||||
|
||||
klass->get_child_position = blur_overlay_get_child_position;
|
||||
|
||||
signals[GET_CHILD_POSITION] =
|
||||
g_signal_new ("get-child-position",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (BlurOverlayClass, get_child_position),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
NULL,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
GTK_TYPE_WIDGET,
|
||||
GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
|
||||
|
||||
child_data_quark = g_quark_from_static_string ("gtk-overlay-child-data");
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "overlay");
|
||||
}
|
||||
|
||||
static void
|
||||
blur_overlay_init (BlurOverlay *overlay)
|
||||
{
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
blur_overlay_new (void)
|
||||
{
|
||||
return g_object_new (BLUR_TYPE_OVERLAY, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
blur_overlay_add_overlay (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
double blur)
|
||||
{
|
||||
BlurOverlayChild *child = g_new0 (BlurOverlayChild, 1);
|
||||
|
||||
gtk_widget_insert_before (widget, GTK_WIDGET (overlay), NULL);
|
||||
|
||||
child->blur = blur;
|
||||
|
||||
blur_overlay_set_overlay_child (widget, child);
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
* bluroverlay.h
|
||||
* This file is part of gtk
|
||||
*
|
||||
* Copyright (C) 2011 - Ignacio Casal Quinteiro, Mike Krüger
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __BLUR_OVERLAY_H__
|
||||
#define __BLUR_OVERLAY_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define BLUR_TYPE_OVERLAY (blur_overlay_get_type ())
|
||||
#define BLUR_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BLUR_TYPE_OVERLAY, BlurOverlay))
|
||||
#define BLUR_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), BLUR_TYPE_OVERLAY, BlurOverlayClass))
|
||||
#define BLUR_IS_OVERLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BLUR_TYPE_OVERLAY))
|
||||
#define BLUR_IS_OVERLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), BLUR_TYPE_OVERLAY))
|
||||
#define BLUR_OVERLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), BLUR_TYPE_OVERLAY, BlurOverlayClass))
|
||||
|
||||
typedef struct _BlurOverlay BlurOverlay;
|
||||
typedef struct _BlurOverlayClass BlurOverlayClass;
|
||||
|
||||
struct _BlurOverlay
|
||||
{
|
||||
GtkBin parent_instance;
|
||||
|
||||
GtkWidget *main_widget;
|
||||
};
|
||||
|
||||
struct _BlurOverlayClass
|
||||
{
|
||||
GtkBinClass parent_class;
|
||||
|
||||
gboolean (*get_child_position) (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GType blur_overlay_get_type (void) G_GNUC_CONST;
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget *blur_overlay_new (void);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void blur_overlay_add_overlay (BlurOverlay *overlay,
|
||||
GtkWidget *widget,
|
||||
double blur);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __BLUR_OVERLAY_H__ */
|
127
demos/gtk-demo/button_box.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/* Button Boxes
|
||||
*
|
||||
* The Button Box widgets are used to arrange buttons with padding.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *
|
||||
create_bbox (gint horizontal,
|
||||
char *title,
|
||||
gint spacing,
|
||||
gint layout)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *bbox;
|
||||
GtkWidget *button;
|
||||
|
||||
frame = gtk_frame_new (title);
|
||||
|
||||
if (horizontal)
|
||||
bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
else
|
||||
bbox = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
|
||||
|
||||
g_object_set (bbox, "margin", 5, NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (frame), bbox);
|
||||
|
||||
gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
|
||||
gtk_box_set_spacing (GTK_BOX (bbox), spacing);
|
||||
|
||||
button = gtk_button_new_with_label (_("OK"));
|
||||
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Cancel"));
|
||||
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Help"));
|
||||
gtk_container_add (GTK_CONTAINER (bbox), button);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_button_box (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *frame_horz;
|
||||
GtkWidget *frame_vert;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed),
|
||||
&window);
|
||||
|
||||
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (main_vbox, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), main_vbox);
|
||||
|
||||
frame_horz = gtk_frame_new ("Horizontal Button Boxes");
|
||||
gtk_widget_set_margin_top (frame_horz, 10);
|
||||
gtk_widget_set_margin_bottom (frame_horz, 10);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
g_object_set (vbox, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Spread", 40, GTK_BUTTONBOX_SPREAD));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Edge", 40, GTK_BUTTONBOX_EDGE));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Start", 40, GTK_BUTTONBOX_START));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "End", 40, GTK_BUTTONBOX_END));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Center", 40, GTK_BUTTONBOX_CENTER));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
create_bbox (TRUE, "Expand", 0, GTK_BUTTONBOX_EXPAND));
|
||||
|
||||
frame_vert = gtk_frame_new ("Vertical Button Boxes");
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
g_object_set (hbox, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Spread", 10, GTK_BUTTONBOX_SPREAD));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Edge", 10, GTK_BUTTONBOX_EDGE));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Start", 10, GTK_BUTTONBOX_START));
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "End", 10, GTK_BUTTONBOX_END));
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Center", 10, GTK_BUTTONBOX_CENTER));
|
||||
gtk_box_pack_start (GTK_BOX (hbox),
|
||||
create_bbox (FALSE, "Expand", 0, GTK_BUTTONBOX_EXPAND));
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -7,7 +7,7 @@
|
||||
* computers, as long as there is a network connection to the
|
||||
* computer where the application is running.
|
||||
*
|
||||
* Only some of the windowing systems where GTK runs have the
|
||||
* Only some of the windowing systems where GTK+ runs have the
|
||||
* concept of multiple displays. (The X Window System is the
|
||||
* main example.) Other windowing systems can only handle one
|
||||
* keyboard and mouse, and combine all monitors into
|
||||
@@ -71,22 +71,30 @@ find_toplevel_at_pointer (GdkDisplay *display)
|
||||
GdkSurface *pointer_window;
|
||||
GtkWidget *widget = NULL;
|
||||
|
||||
pointer_window = gdk_device_get_surface_at_position (gtk_get_current_event_device (), NULL, NULL);
|
||||
pointer_window = gdk_device_get_surface_at_position (gtk_get_current_event_device (),
|
||||
NULL, NULL);
|
||||
|
||||
/* The user data field of a GdkSurface is used to store a pointer
|
||||
* to the widget that created it.
|
||||
*/
|
||||
if (pointer_window)
|
||||
widget = GTK_WIDGET (gtk_native_get_for_surface (pointer_window));
|
||||
{
|
||||
gpointer widget_ptr;
|
||||
gdk_surface_get_user_data (pointer_window, &widget_ptr);
|
||||
widget = widget_ptr;
|
||||
}
|
||||
|
||||
return widget;
|
||||
return widget ? gtk_widget_get_toplevel (widget) : NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
released_cb (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gboolean *clicked)
|
||||
static gboolean
|
||||
release_event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gboolean *clicked)
|
||||
{
|
||||
*clicked = TRUE;
|
||||
if (gdk_event_get_event_type (event) == GDK_BUTTON_RELEASE)
|
||||
*clicked = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Asks the user to click on a window, then waits for them click
|
||||
@@ -105,6 +113,7 @@ query_for_toplevel (GdkDisplay *display,
|
||||
popup = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
gtk_window_set_display (GTK_WINDOW (popup), display);
|
||||
gtk_window_set_modal (GTK_WINDOW (popup), TRUE);
|
||||
gtk_window_set_position (GTK_WINDOW (popup), GTK_WIN_POS_CENTER);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
|
||||
@@ -119,16 +128,14 @@ query_for_toplevel (GdkDisplay *display,
|
||||
device = gtk_get_current_event_device ();
|
||||
|
||||
if (gdk_seat_grab (gdk_device_get_seat (device),
|
||||
gtk_native_get_surface (GTK_NATIVE (popup)),
|
||||
gtk_widget_get_surface (popup),
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
|
||||
{
|
||||
GtkGesture *gesture = gtk_gesture_click_new ();
|
||||
gboolean clicked = FALSE;
|
||||
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (released_cb), &clicked);
|
||||
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_signal_connect (popup, "event",
|
||||
G_CALLBACK (release_event_cb), &clicked);
|
||||
|
||||
/* Process events until clicked is set by our button release event handler.
|
||||
* We pass in may_block=TRUE since we want to wait if there
|
||||
@@ -137,8 +144,6 @@ query_for_toplevel (GdkDisplay *display,
|
||||
while (!clicked)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
gdk_seat_ungrab (gdk_device_get_seat (device));
|
||||
|
||||
toplevel = find_toplevel_at_pointer (display);
|
||||
if (toplevel == popup)
|
||||
toplevel = NULL;
|
||||
@@ -306,7 +311,7 @@ create_frame (ChangeDisplayInfo *info,
|
||||
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin),
|
||||
GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), scrollwin);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), scrollwin);
|
||||
|
||||
*tree_view = gtk_tree_view_new ();
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE);
|
||||
@@ -316,7 +321,7 @@ create_frame (ChangeDisplayInfo *info,
|
||||
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
|
||||
|
||||
*button_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), *button_vbox);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), *button_vbox);
|
||||
|
||||
if (!info->size_group)
|
||||
info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
@@ -356,11 +361,11 @@ create_display_frame (ChangeDisplayInfo *info)
|
||||
|
||||
button = left_align_button_new ("_Open...");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (open_display_cb), info);
|
||||
gtk_container_add (GTK_CONTAINER (button_vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (button_vbox), button);
|
||||
|
||||
button = left_align_button_new ("_Close");
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (close_display_cb), info);
|
||||
gtk_container_add (GTK_CONTAINER (button_vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (button_vbox), button);
|
||||
|
||||
info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS,
|
||||
G_TYPE_STRING,
|
||||
@@ -533,10 +538,10 @@ do_changedisplay (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
g_object_set (vbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), vbox);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), vbox);
|
||||
|
||||
frame = create_display_frame (info);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
initialize_displays (info);
|
||||
|
||||
|
@@ -28,7 +28,7 @@ copy_button_clicked (GtkWidget *button,
|
||||
clipboard = gtk_widget_get_clipboard (entry);
|
||||
|
||||
/* Set clipboard text */
|
||||
gdk_clipboard_set_text (clipboard, gtk_editable_get_text (GTK_EDITABLE (entry)));
|
||||
gdk_clipboard_set_text (clipboard, gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -50,7 +50,7 @@ paste_received (GObject *source_object,
|
||||
if (text)
|
||||
{
|
||||
/* Set the entry text */
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), text);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
||||
g_free (text);
|
||||
}
|
||||
else
|
||||
@@ -120,7 +120,7 @@ get_image_paintable (GtkImage *image)
|
||||
|
||||
static void
|
||||
drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GdkDragContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -128,16 +128,17 @@ drag_begin (GtkWidget *widget,
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
|
||||
gtk_drag_set_icon_paintable (context, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
@@ -149,8 +150,9 @@ drag_data_get (GtkWidget *widget,
|
||||
|
||||
static void
|
||||
drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint32 time,
|
||||
gpointer data)
|
||||
{
|
||||
if (gtk_selection_data_get_length (selection_data) > 0)
|
||||
@@ -259,45 +261,45 @@ do_clipboard (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new ("\"Copy\" will copy the text\nin the entry to the clipboard");
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Copy"));
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (copy_button_clicked), entry);
|
||||
|
||||
label = gtk_label_new ("\"Paste\" will paste the text from the clipboard to the entry");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_container_add (GTK_CONTAINER (hbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), entry);
|
||||
|
||||
/* Create the button */
|
||||
button = gtk_button_new_with_mnemonic (_("_Paste"));
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (paste_button_clicked), entry);
|
||||
|
||||
label = gtk_label_new ("Images can be transferred via the clipboard, too");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
/* Create the first image */
|
||||
image = gtk_image_new_from_icon_name ("dialog-warning");
|
||||
@@ -319,10 +321,10 @@ do_clipboard (GtkWidget *do_widget)
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gesture = gtk_gesture_multi_press_new (image);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_object_set_data_full (G_OBJECT (image), "gesture", gesture, g_object_unref);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* Create the second image */
|
||||
image = gtk_image_new_from_icon_name ("process-stop");
|
||||
@@ -344,10 +346,10 @@ do_clipboard (GtkWidget *do_widget)
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gesture = gtk_gesture_multi_press_new (image);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_object_set_data_full (G_OBJECT (image), "gesture", gesture, g_object_unref);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* Color Chooser
|
||||
*
|
||||
* A GtkColorChooser lets the user choose a color. There are several
|
||||
* implementations of the GtkColorChooser interface in GTK. The
|
||||
* implementations of the GtkColorChooser interface in GTK+. The
|
||||
* GtkColorChooserDialog is a prebuilt dialog containing a
|
||||
* GtkColorChooserWidget.
|
||||
*/
|
||||
@@ -88,7 +88,7 @@ do_colorsel (GtkWidget *do_widget)
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 200);
|
||||
@@ -101,7 +101,7 @@ do_colorsel (GtkWidget *do_widget)
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button);
|
||||
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_color_callback), NULL);
|
||||
|
@@ -144,7 +144,7 @@ create_capital_store (void)
|
||||
{ NULL, "Jackson" },
|
||||
{ NULL, "Jefferson City" },
|
||||
{ NULL, "Juneau" },
|
||||
{ "K - O", NULL },
|
||||
{ "K - O" },
|
||||
{ NULL, "Lansing" },
|
||||
{ NULL, "Lincoln" },
|
||||
{ NULL, "Little Rock" },
|
||||
@@ -154,7 +154,7 @@ create_capital_store (void)
|
||||
{ NULL, "Nashville" },
|
||||
{ NULL, "Oklahoma City" },
|
||||
{ NULL, "Olympia" },
|
||||
{ "P - S", NULL },
|
||||
{ NULL, "P - S" },
|
||||
{ NULL, "Phoenix" },
|
||||
{ NULL, "Pierre" },
|
||||
{ NULL, "Providence" },
|
||||
@@ -256,7 +256,7 @@ mask_entry_set_background (MaskEntry *entry)
|
||||
{
|
||||
if (entry->mask)
|
||||
{
|
||||
if (!g_regex_match_simple (entry->mask, gtk_editable_get_text (GTK_EDITABLE (entry)), 0, 0))
|
||||
if (!g_regex_match_simple (entry->mask, gtk_entry_get_text (GTK_ENTRY (entry)), 0, 0))
|
||||
{
|
||||
PangoAttrList *attrs;
|
||||
|
||||
@@ -326,7 +326,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
* insensitive rows
|
||||
*/
|
||||
frame = gtk_frame_new ("Items with icons");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
@@ -367,7 +367,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
/* A combobox demonstrating trees.
|
||||
*/
|
||||
frame = gtk_frame_new ("Where are we ?");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
@@ -395,7 +395,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
|
||||
/* A GtkComboBoxEntry with validation */
|
||||
frame = gtk_frame_new ("Editable");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
@@ -413,7 +413,7 @@ do_combobox (GtkWidget *do_widget)
|
||||
|
||||
/* A combobox with string IDs */
|
||||
frame = gtk_frame_new ("String IDs");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
g_object_set (box, "margin", 5, NULL);
|
||||
|
@@ -1,257 +0,0 @@
|
||||
/* Constraints/Simple
|
||||
*
|
||||
* GtkConstraintLayout provides a layout manager that uses relations
|
||||
* between widgets (also known as "constraints") to compute the position
|
||||
* and size of each child.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SimpleGrid, simple_grid, SIMPLE, GRID, GtkWidget)
|
||||
|
||||
struct _SimpleGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *button1, *button2;
|
||||
GtkWidget *button3;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SimpleGrid, simple_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
simple_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
SimpleGrid *self = SIMPLE_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
|
||||
GTK_WIDGET_CLASS (simple_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_grid_class_init (SimpleGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = simple_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
/* Layout:
|
||||
*
|
||||
* +-----------------------------+
|
||||
* | +-----------+ +-----------+ |
|
||||
* | | Child 1 | | Child 2 | |
|
||||
* | +-----------+ +-----------+ |
|
||||
* | +-------------------------+ |
|
||||
* | | Child 3 | |
|
||||
* | +-------------------------+ |
|
||||
* +-----------------------------+
|
||||
*
|
||||
* Constraints:
|
||||
*
|
||||
* super.start = child1.start - 8
|
||||
* child1.width = child2.width
|
||||
* child1.end = child2.start - 12
|
||||
* child2.end = super.end - 8
|
||||
* super.start = child3.start - 8
|
||||
* child3.end = super.end - 8
|
||||
* super.top = child1.top - 8
|
||||
* super.top = child2.top - 8
|
||||
* child1.bottom = child3.top - 12
|
||||
* child2.bottom = child3.top - 12
|
||||
* child3.height = child1.height
|
||||
* child3.height = child2.height
|
||||
* child3.bottom = super.bottom - 8
|
||||
*
|
||||
*/
|
||||
static void
|
||||
build_constraints (SimpleGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-12.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-12.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-12.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
}
|
||||
|
||||
static void
|
||||
simple_grid_init (SimpleGrid *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
|
||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
||||
gtk_widget_set_parent (self->button1, widget);
|
||||
gtk_widget_set_name (self->button1, "button1");
|
||||
|
||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
||||
gtk_widget_set_parent (self->button2, widget);
|
||||
gtk_widget_set_name (self->button2, "button2");
|
||||
|
||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
||||
gtk_widget_set_parent (self->button3, widget);
|
||||
gtk_widget_set_name (self->button3, "button3");
|
||||
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_constraints (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (simple_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -1,190 +0,0 @@
|
||||
/* Constraints/Grid
|
||||
*
|
||||
* GtkConstraintLayout lets you define complex layouts
|
||||
* like grids.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ComplexGrid, complex_grid, COMPLEX, GRID, GtkWidget)
|
||||
|
||||
struct _ComplexGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *button1, *button2, *button3;
|
||||
GtkWidget *button4, *button5;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ComplexGrid, complex_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
complex_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
ComplexGrid *self = COMPLEX_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button4, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button5, gtk_widget_destroy);
|
||||
|
||||
GTK_WIDGET_CLASS (complex_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
complex_grid_class_init (ComplexGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = complex_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
/* Layout:
|
||||
*
|
||||
* +--------------------------------------+
|
||||
* | +-----------+ |
|
||||
* | | Child 4 | |
|
||||
* | +-----------+-----------+----------+ |
|
||||
* | | Child 1 | Child 2 | Child 3 | |
|
||||
* | +-----------+-----------+----------+ |
|
||||
* | | Child 5 | |
|
||||
* | +-----------+ |
|
||||
* +--------------------------------------+
|
||||
*
|
||||
*/
|
||||
static void
|
||||
build_constraints (ComplexGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
GtkGridConstraint *constraint;
|
||||
GtkConstraint *s;
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1, GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (self->button3, GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL, GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button4, GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
s = gtk_constraint_new (NULL, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button5, GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (manager, s);
|
||||
|
||||
constraint = gtk_grid_constraint_new ();
|
||||
g_object_set (constraint, "column-homogeneous", TRUE, NULL);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button1,
|
||||
0, 1, 0, 1);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button2,
|
||||
1, 2, 0, 1);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button3,
|
||||
2, 3, 0, 1);
|
||||
gtk_constraint_layout_add_grid_constraint (manager, constraint);
|
||||
|
||||
constraint = gtk_grid_constraint_new ();
|
||||
g_object_set (constraint, "row-homogeneous", TRUE, NULL);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button4,
|
||||
0, 1, 0, 1);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button2,
|
||||
0, 1, 1, 2);
|
||||
gtk_grid_constraint_add (constraint,
|
||||
self->button5,
|
||||
0, 1, 2, 3);
|
||||
gtk_constraint_layout_add_grid_constraint (manager, constraint);
|
||||
}
|
||||
|
||||
static void
|
||||
complex_grid_init (ComplexGrid *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
|
||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
||||
gtk_widget_set_parent (self->button1, widget);
|
||||
gtk_widget_set_name (self->button1, "button1");
|
||||
|
||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
||||
gtk_widget_set_parent (self->button2, widget);
|
||||
gtk_widget_set_name (self->button2, "button2");
|
||||
|
||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
||||
gtk_widget_set_parent (self->button3, widget);
|
||||
gtk_widget_set_name (self->button3, "button3");
|
||||
|
||||
self->button4 = gtk_button_new_with_label ("Child 4");
|
||||
gtk_widget_set_parent (self->button4, widget);
|
||||
gtk_widget_set_name (self->button4, "button4");
|
||||
|
||||
self->button5 = gtk_button_new_with_label ("Child 5");
|
||||
gtk_widget_set_parent (self->button5, widget);
|
||||
gtk_widget_set_name (self->button5, "button5");
|
||||
|
||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_constraints2 (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (complex_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -1,355 +0,0 @@
|
||||
/* Constraints/Words
|
||||
*
|
||||
* GtkConstraintLayout lets you define big grids.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define WORDS_TYPE_BASE (words_base_get_type ())
|
||||
#define WORDS_TYPE_GRID (words_grid_get_type ())
|
||||
#define WORDS_TYPE_CONSTRAINT (words_constraint_get_type ())
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
} WordsBase;
|
||||
|
||||
typedef WordsBase WordsGrid;
|
||||
typedef WordsBase WordsConstraint;
|
||||
|
||||
typedef GtkWidgetClass WordsBaseClass;
|
||||
typedef GtkWidgetClass WordsGridClass;
|
||||
typedef GtkWidgetClass WordsConstraintClass;
|
||||
|
||||
G_DEFINE_TYPE (WordsBase, words_base, GTK_TYPE_WIDGET)
|
||||
G_DEFINE_TYPE (WordsGrid, words_grid, WORDS_TYPE_BASE)
|
||||
G_DEFINE_TYPE (WordsConstraint, words_constraint, WORDS_TYPE_BASE)
|
||||
|
||||
static void
|
||||
words_grid_init (WordsGrid *words)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
words_grid_class_init (WordsGridClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_GRID_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
words_constraint_init (WordsGrid *words)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
words_constraint_class_init (WordsConstraintClass *class)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
word_base_dispose (GObject *object)
|
||||
{
|
||||
GtkWidget *self = GTK_WIDGET (object);
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (self)) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (words_base_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
words_base_class_init (WordsBaseClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = word_base_dispose;
|
||||
}
|
||||
|
||||
static int num_words = 100;
|
||||
static gboolean use_constraints = FALSE;
|
||||
|
||||
static void
|
||||
read_words (WordsBase *self)
|
||||
{
|
||||
GBytes *data;
|
||||
const char *words;
|
||||
int left, top;
|
||||
GtkWidget *child = NULL;
|
||||
GtkLayoutManager *layout = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
GtkGridConstraint *grid;
|
||||
GtkConstraint *constraint;
|
||||
int count;
|
||||
int rightmost;
|
||||
GtkWidget *right_child = NULL;
|
||||
gboolean use_constraint = GTK_IS_CONSTRAINT_LAYOUT (layout);
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
grid = gtk_grid_constraint_new ();
|
||||
g_object_set (grid,
|
||||
"row-homogeneous", TRUE,
|
||||
"column-homogeneous", FALSE,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_grid_layout_set_row_homogeneous (GTK_GRID_LAYOUT (layout), TRUE);
|
||||
gtk_grid_layout_set_column_homogeneous (GTK_GRID_LAYOUT (layout), FALSE);
|
||||
}
|
||||
|
||||
data = g_resources_lookup_data ("/constraints3/words", 0, NULL);
|
||||
words = g_bytes_get_data (data, NULL);
|
||||
count = 0;
|
||||
|
||||
rightmost = 0;
|
||||
left = 0;
|
||||
top = 0;
|
||||
while (words && words[0])
|
||||
{
|
||||
char *p = strchr (words, '\n');
|
||||
char *word;
|
||||
int len;
|
||||
|
||||
if (p)
|
||||
{
|
||||
word = strndup (words, p - words);
|
||||
words = p + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
word = strdup (words);
|
||||
words = NULL;
|
||||
}
|
||||
|
||||
len = strlen (word);
|
||||
child = gtk_button_new_with_label (word);
|
||||
|
||||
if (left + len > 50)
|
||||
{
|
||||
top++;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
|
||||
if (left + len > rightmost)
|
||||
{
|
||||
rightmost = left + len;
|
||||
right_child = child;
|
||||
}
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
gtk_grid_constraint_add (grid, child,
|
||||
left, left + len,
|
||||
top, top + 1);
|
||||
if (left == 0 && top == 0)
|
||||
{
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkGridLayoutChild *grid_child = GTK_GRID_LAYOUT_CHILD (gtk_layout_manager_get_layout_child (layout, child));
|
||||
|
||||
g_object_set (grid_child,
|
||||
"left-attach", left,
|
||||
"top-attach", top,
|
||||
"column-span", len,
|
||||
"row-span", 1,
|
||||
NULL);
|
||||
}
|
||||
|
||||
left = left + len;
|
||||
count++;
|
||||
|
||||
if (count >= num_words)
|
||||
break;
|
||||
}
|
||||
|
||||
if (use_constraint)
|
||||
{
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
right_child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
constraint = gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
constraint);
|
||||
|
||||
gtk_constraint_layout_add_grid_constraint (GTK_CONSTRAINT_LAYOUT (layout),
|
||||
grid);
|
||||
}
|
||||
|
||||
g_bytes_unref (data);
|
||||
}
|
||||
|
||||
static void
|
||||
words_base_init (WordsBase *self)
|
||||
{
|
||||
read_words (self);
|
||||
}
|
||||
|
||||
static void
|
||||
show_words (GtkWidget *parent)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
GtkWidget *swin;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
||||
GTK_WINDOW (gtk_widget_get_root (parent)));
|
||||
gtk_window_set_modal (GTK_WINDOW (window), TRUE);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), use_constraints ? "Constraints" : "Grid");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
swin = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_propagate_natural_width (GTK_SCROLLED_WINDOW (swin), TRUE);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (swin), TRUE);
|
||||
gtk_widget_set_hexpand (swin, TRUE);
|
||||
gtk_widget_set_vexpand (swin, TRUE);
|
||||
gtk_widget_set_halign (swin, GTK_ALIGN_FILL);
|
||||
gtk_widget_set_valign (swin, GTK_ALIGN_FILL);
|
||||
gtk_container_add (GTK_CONTAINER (box), swin);
|
||||
|
||||
if (use_constraints)
|
||||
grid = g_object_new (WORDS_TYPE_CONSTRAINT, NULL);
|
||||
else
|
||||
grid = g_object_new (WORDS_TYPE_GRID, NULL);
|
||||
|
||||
gtk_widget_set_halign (swin, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (swin, GTK_ALIGN_START);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (swin), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
use_constraints_cb (GtkButton *button)
|
||||
{
|
||||
use_constraints = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
||||
}
|
||||
|
||||
static void
|
||||
word_count_cb (GtkSpinButton *button)
|
||||
{
|
||||
num_words = gtk_spin_button_get_value_as_int (button);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_constraints3 (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *grid, *button, *label;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Words");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), TRUE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
g_object_set (grid,
|
||||
"margin", 12,
|
||||
"row-spacing", 12,
|
||||
"column-spacing", 6,
|
||||
"halign", GTK_ALIGN_FILL,
|
||||
"valign", GTK_ALIGN_FILL,
|
||||
"hexpand", TRUE,
|
||||
"vexpand", TRUE,
|
||||
NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), grid);
|
||||
|
||||
label = gtk_label_new ("Constraints:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
|
||||
button = gtk_check_button_new ();
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (use_constraints_cb), NULL);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);
|
||||
label = gtk_label_new ("Words:");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 1.0);
|
||||
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
|
||||
button = gtk_spin_button_new_with_range (0, 1300, 1);
|
||||
g_signal_connect (button, "value-changed", G_CALLBACK (word_count_cb), NULL);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (button), 10);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1);
|
||||
|
||||
button = gtk_button_new_with_label ("Show");
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_END);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (show_words), window);
|
||||
gtk_grid_attach (GTK_GRID (grid), button, 0, 2, 2, 1);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -13,22 +13,19 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
@@ -13,23 +13,19 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
@@ -12,23 +12,19 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
@@ -11,22 +11,19 @@ show_parsing_error (GtkCssProvider *provider,
|
||||
const GError *error,
|
||||
GtkTextBuffer *buffer)
|
||||
{
|
||||
const GtkCssLocation *start_location, *end_location;
|
||||
GtkTextIter start, end;
|
||||
const char *tag_name;
|
||||
|
||||
start_location = gtk_css_section_get_start_location (section);
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&start,
|
||||
start_location->lines,
|
||||
start_location->line_bytes);
|
||||
end_location = gtk_css_section_get_end_location (section);
|
||||
gtk_css_section_get_start_line (section),
|
||||
gtk_css_section_get_start_position (section));
|
||||
gtk_text_buffer_get_iter_at_line_index (buffer,
|
||||
&end,
|
||||
end_location->lines,
|
||||
end_location->line_bytes);
|
||||
gtk_css_section_get_end_line (section),
|
||||
gtk_css_section_get_end_position (section));
|
||||
|
||||
if (error->domain == GTK_CSS_PARSER_WARNING)
|
||||
if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
|
||||
tag_name = "warning";
|
||||
else
|
||||
tag_name = "error";
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.94 -->
|
||||
<object class="GdkCursor" id="default_cursor">
|
||||
<property name="name">default</property>
|
||||
</object>
|
||||
|
BIN
demos/gtk-demo/data/16x16/gtk4-demo-symbolic.symbolic.png
Normal file
After Width: | Height: | Size: 324 B |
BIN
demos/gtk-demo/data/16x16/gtk4-demo.png
Normal file
After Width: | Height: | Size: 874 B |
BIN
demos/gtk-demo/data/22x22/gtk4-demo-symbolic.symbolic.png
Normal file
After Width: | Height: | Size: 437 B |
BIN
demos/gtk-demo/data/22x22/gtk4-demo.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
demos/gtk-demo/data/24x24/gtk4-demo-symbolic.symbolic.png
Normal file
After Width: | Height: | Size: 465 B |
BIN
demos/gtk-demo/data/24x24/gtk4-demo.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
demos/gtk-demo/data/256x256/gtk4-demo-symbolic.symbolic.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
demos/gtk-demo/data/256x256/gtk4-demo.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
demos/gtk-demo/data/32x32/gtk4-demo-symbolic.symbolic.png
Normal file
After Width: | Height: | Size: 581 B |
BIN
demos/gtk-demo/data/32x32/gtk4-demo.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
demos/gtk-demo/data/48x48/gtk4-demo-symbolic.symbolic.png
Normal file
After Width: | Height: | Size: 854 B |
BIN
demos/gtk-demo/data/48x48/gtk4-demo.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
demos/gtk-demo/data/512x512/gtk4-demo-symbolic.symbolic.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
demos/gtk-demo/data/512x512/gtk4-demo.png
Normal file
After Width: | Height: | Size: 41 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128" version="1.0"><defs><linearGradient id="f"><stop offset="0" stop-color="#ff7800"/><stop offset="1" stop-color="#ed333b"/></linearGradient><linearGradient id="e"><stop offset="0" stop-color="#f5c211"/><stop offset="1" stop-color="#33d17a" stop-opacity=".899"/></linearGradient><linearGradient id="d"><stop offset="0" stop-color="#c0bfbc"/><stop offset=".036" stop-color="#fafaf9"/><stop offset=".088" stop-color="#c0bfbc"/><stop offset=".399" stop-color="#d5d5d3"/><stop offset=".491" stop-color="#eaeae9"/><stop offset=".569" stop-color="#a7a5a1"/><stop offset=".966" stop-color="#a9a7a3"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="a"><stop offset="0" stop-color="#d5d3cf"/><stop offset="1" stop-color="#f6f5f4"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#d5d3cf"/><stop offset="1" stop-color="#949390"/></linearGradient><linearGradient id="c"><stop offset="0" stop-color="#9a9996"/><stop offset="1" stop-color="#77767b"/></linearGradient><linearGradient xlink:href="#d" id="g" x1="-142.049" y1="236.001" x2="-9.951" y2="236.001" gradientUnits="userSpaceOnUse"/><radialGradient xlink:href="#e" id="h" cx="90.974" cy="263.479" fx="90.974" fy="263.479" r="22.703" gradientTransform="matrix(1.90297 -.05506 .0501 1.73133 -89.25 -176.863)" gradientUnits="userSpaceOnUse"/><radialGradient xlink:href="#f" id="i" cx="61.718" cy="270.719" fx="61.718" fy="270.719" r="22.703" gradientTransform="matrix(2.49049 0 0 2.92132 -91.99 -503.52)" gradientUnits="userSpaceOnUse"/></defs><path transform="translate(123.265 -118.118) scale(.7798)" d="M-75.74 161.438a10.997 10.997 0 0 0-5.758 1.468l-55.053 31.785a10.997 10.997 0 0 0-5.498 9.524v63.57a10.997 10.997 0 0 0 5.498 9.524l55.053 31.785a10.997 10.997 0 0 0 10.996 0l55.053-31.785a10.997 10.997 0 0 0 5.498-9.524v-63.57a10.997 10.997 0 0 0-5.498-9.524l-55.053-31.785a10.997 10.997 0 0 0-5.238-1.469z" style="marker:none" fill="url(#g)"/><path style="marker:none" d="M64.203 3.77a8.575 8.575 0 0 0-4.49 1.146l-42.93 24.786a8.575 8.575 0 0 0-4.288 7.427V86.7a8.575 8.575 0 0 0 4.287 7.426l42.93 24.786a8.575 8.575 0 0 0 8.575 0l42.93-24.786a8.575 8.575 0 0 0 4.288-7.426V37.129a8.575 8.575 0 0 0-4.287-7.427L68.288 4.916a8.575 8.575 0 0 0-4.085-1.145z" fill="#fff"/><path style="marker:none" d="M109.869 33.297L64 59.779 18.131 33.297 64 6.814z" fill="#98c1f1"/><path style="marker:none" d="M66.263 287.505l45.35-25.884.056-52.762-45.406 26.215z" fill="url(#h)" transform="translate(0 -172)"/><path d="M61.718 287.34l-45.35-25.885-.056-52.761 45.406 26.215z" style="marker:none" fill="url(#i)" transform="translate(0 -172)"/></svg>
|
Before Width: | Height: | Size: 2.7 KiB |
2886
demos/gtk-demo/data/source.svg
Normal file
After Width: | Height: | Size: 101 KiB |
29
demos/gtk-demo/data/symbolic-source.svg
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='gtk3-demo-symbolic.svg' height='16.000015' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:osb='http://www.openswatchbook.org/uri/2009/osb' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.5 r10040' version='1.1' width='16' xmlns='http://www.w3.org/2000/svg'>
|
||||
<metadata id='metadata90'>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about=''>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer9' inkscape:cx='-12.5126' inkscape:cy='-0.73412416' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#555753' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape:snap-bbox='true' inkscape:snap-bbox-midpoints='false' inkscape:snap-global='true' inkscape:snap-grids='true' inkscape:snap-nodes='true' inkscape:snap-others='false' inkscape:snap-to-guides='true' inkscape:window-height='1375' inkscape:window-maximized='1' inkscape:window-width='2560' inkscape:window-x='0' inkscape:window-y='27' inkscape:zoom='5.6568542'>
|
||||
<inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='-182.99998px' originy='-251.99998px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
|
||||
</sodipodi:namedview>
|
||||
<title id='title9167'>Gnome Symbolic Icon Theme</title>
|
||||
<defs id='defs7386'>
|
||||
<linearGradient id='linearGradient7212' osb:paint='solid'>
|
||||
<stop id='stop7214' offset='0' style='stop-color:#000000;stop-opacity:1;'/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g inkscape:groupmode='layer' id='layer9' inkscape:label='apps' style='display:inline' transform='translate(-424.00018,35)'>
|
||||
|
||||
<rect height='8.0000048' id='rect7866' style='opacity:0.3;color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new' transform='matrix(0.83205029,0.5547002,0,1,0,0)' width='7.2111053' x='510.78668' y='-314.33347'/>
|
||||
<rect height='8.0000086' id='rect7868' style='opacity:0.5;color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new' transform='matrix(-0.86824295,0.49613928,0,1,0,0)' width='8.0622425' x='-505.61908' y='219.8575'/>
|
||||
<path inkscape:connector-curvature='0' d='m 431.53145,-28 -5.875,-3.65625 6.8125,-3.34375 6.03125,3 z' id='path7870' sodipodi:nodetypes='ccccc' style='color:#000000;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.39999998;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:new'/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
@@ -1,114 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="org.gtk.Demo4-symbolic.svg"
|
||||
height="16.03125"
|
||||
id="svg7384"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
version="1.1"
|
||||
width="16">
|
||||
<metadata
|
||||
id="metadata90">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Gnome Symbolic Icon Theme</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
inkscape:bbox-paths="true"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
inkscape:current-layer="layer9"
|
||||
inkscape:cx="0.53203442"
|
||||
inkscape:cy="9.1822592"
|
||||
gridtolerance="10"
|
||||
inkscape:guide-bbox="true"
|
||||
guidetolerance="10"
|
||||
id="namedview88"
|
||||
inkscape:object-nodes="false"
|
||||
inkscape:object-paths="false"
|
||||
objecttolerance="10"
|
||||
pagecolor="#555753"
|
||||
inkscape:pageopacity="1"
|
||||
inkscape:pageshadow="2"
|
||||
showborder="true"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-bbox-midpoints="false"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-grids="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-others="false"
|
||||
inkscape:snap-to-guides="true"
|
||||
inkscape:window-height="1375"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:zoom="1">
|
||||
<inkscape:grid
|
||||
empspacing="2"
|
||||
enabled="true"
|
||||
id="grid4866"
|
||||
originx="-203"
|
||||
originy="-251.96875"
|
||||
snapvisiblegridlinesonly="true"
|
||||
spacingx="1"
|
||||
spacingy="1"
|
||||
type="xygrid"
|
||||
visible="true" />
|
||||
</sodipodi:namedview>
|
||||
<title
|
||||
id="title9167">Gnome Symbolic Icon Theme</title>
|
||||
<defs
|
||||
id="defs7386">
|
||||
<linearGradient
|
||||
id="linearGradient7212"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
id="stop7214"
|
||||
offset="0"
|
||||
style="stop-color:#000000;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer9"
|
||||
inkscape:label="apps"
|
||||
style="display:inline"
|
||||
transform="translate(-444.0002,35)">
|
||||
<path
|
||||
style="display:inline;opacity:0.3;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
d="m 457.97232,-31.569556 -5.96212,3.44224 -5.96215,-3.44224 v 0 l 5.96215,-3.44226 z"
|
||||
id="path870-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
<path
|
||||
sodipodi:nodetypes="cccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path886-9"
|
||||
d="m 450.98519,-19.648086 -5.99273,-3.42041 -0.007,-6.97219 v 0 l 6.00018,3.4642 z"
|
||||
style="display:inline;opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new" />
|
||||
<path
|
||||
style="display:inline;opacity:0.60100002;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:normal;enable-background:new"
|
||||
d="m 452.98577,-19.648086 5.99273,-3.42041 0.007,-6.97219 v 0 l -6.00018,3.4642 z"
|
||||
id="path931"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 4.3 KiB |
@@ -12,9 +12,6 @@
|
||||
<gresource prefix="/builder">
|
||||
<file>demo.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/constraints3">
|
||||
<file>words</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_accordion">
|
||||
<file>css_accordion.css</file>
|
||||
<file>reset.css</file>
|
||||
@@ -40,9 +37,6 @@
|
||||
<gresource prefix="/theming_style_classes">
|
||||
<file>theming.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/themes">
|
||||
<file>themes.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/css_pixbufs">
|
||||
<file alias="gtk.css">css_pixbufs.css</file>
|
||||
<file>cssview.css</file>
|
||||
@@ -111,6 +105,9 @@
|
||||
<file>gnome-fs-directory.png</file>
|
||||
<file>gnome-fs-regular.png</file>
|
||||
</gresource>
|
||||
<gresource prefix="/stack">
|
||||
<file>stack.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/shortcuts">
|
||||
<file>shortcuts.ui</file>
|
||||
<file>shortcuts-builder.ui</file>
|
||||
@@ -118,14 +115,6 @@
|
||||
<file>shortcuts-clocks.ui</file>
|
||||
<file>shortcuts-boxes.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/sliding_puzzle">
|
||||
<file>puzzlepiece.c</file>
|
||||
<file>puzzlepiece.h</file>
|
||||
<file>portland-rose.jpg</file>
|
||||
</gresource>
|
||||
<gresource prefix="/stack">
|
||||
<file>stack.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/revealer">
|
||||
<file>revealer.ui</file>
|
||||
</gresource>
|
||||
@@ -149,13 +138,11 @@
|
||||
<file>application_demo.c</file>
|
||||
<file>assistant.c</file>
|
||||
<file>builder.c</file>
|
||||
<file>button_box.c</file>
|
||||
<file>changedisplay.c</file>
|
||||
<file>clipboard.c</file>
|
||||
<file>colorsel.c</file>
|
||||
<file>combobox.c</file>
|
||||
<file>constraints.c</file>
|
||||
<file>constraints2.c</file>
|
||||
<file>constraints3.c</file>
|
||||
<file>css_accordion.c</file>
|
||||
<file>css_basics.c</file>
|
||||
<file>css_blendmodes.c</file>
|
||||
@@ -169,10 +156,11 @@
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_buffer.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
<file>event_axes.c</file>
|
||||
<file>expander.c</file>
|
||||
<file>filtermodel.c</file>
|
||||
<file>fishbowl.c</file>
|
||||
<file>fixed.c</file>
|
||||
<file>widgetbowl.c</file>
|
||||
<file>flowbox.c</file>
|
||||
<file>foreigndrawing.c</file>
|
||||
<file>font_features.c</file>
|
||||
@@ -193,13 +181,11 @@
|
||||
<file>modelbutton.c</file>
|
||||
<file>overlay.c</file>
|
||||
<file>overlay2.c</file>
|
||||
<file>paint.c</file>
|
||||
<file>pagesetup.c</file>
|
||||
<file>paintable.c</file>
|
||||
<file>paintable_animated.c</file>
|
||||
<file>paintable_mediastream.c</file>
|
||||
<file>panes.c</file>
|
||||
<file>password_entry.c</file>
|
||||
<file>pickers.c</file>
|
||||
<file>pixbufs.c</file>
|
||||
<file>popover.c</file>
|
||||
@@ -212,16 +198,13 @@
|
||||
<file>shortcuts.c</file>
|
||||
<file>sizegroup.c</file>
|
||||
<file>sidebar.c</file>
|
||||
<file>sliding_puzzle.c</file>
|
||||
<file>stack.c</file>
|
||||
<file>spinbutton.c</file>
|
||||
<file>spinner.c</file>
|
||||
<file>tabs.c</file>
|
||||
<file>tagged_entry.c</file>
|
||||
<file>textview.c</file>
|
||||
<file>textscroll.c</file>
|
||||
<file>theming_style_classes.c</file>
|
||||
<file>themes.c</file>
|
||||
<file>transparent.c</file>
|
||||
<file>tree_store.c</file>
|
||||
<file>textmask.c</file>
|
||||
@@ -230,9 +213,6 @@
|
||||
<gresource prefix="/textview">
|
||||
<file>floppybuddy.gif</file>
|
||||
</gresource>
|
||||
<gresource prefix="/tagged_entry">
|
||||
<file>tagstyle.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/listbox">
|
||||
<file>listbox.ui</file>
|
||||
<file>messages.txt</file>
|
||||
@@ -263,7 +243,6 @@
|
||||
</gresource>
|
||||
<gresource prefix="/transparent">
|
||||
<file>portland-rose.jpg</file>
|
||||
<file>bluroverlay.c</file>
|
||||
</gresource>
|
||||
<gresource prefix="/markup">
|
||||
<file>markup.txt</file>
|
||||
@@ -277,30 +256,4 @@
|
||||
<gresource prefix="/dnd">
|
||||
<file>dnd.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/tagged_entry">
|
||||
<file>demotaggedentry.c</file>
|
||||
<file>demotaggedentry.h</file>
|
||||
</gresource>
|
||||
<gresource prefix="/fixed">
|
||||
<file>fixed.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4">
|
||||
<file>icons/16x16/actions/application-exit.png</file>
|
||||
<file>icons/16x16/actions/document-new.png</file>
|
||||
<file>icons/16x16/actions/document-open.png</file>
|
||||
<file>icons/16x16/actions/document-save.png</file>
|
||||
<file>icons/16x16/actions/edit-copy.png</file>
|
||||
<file>icons/16x16/actions/edit-cut.png</file>
|
||||
<file>icons/16x16/actions/edit-paste.png</file>
|
||||
<file>icons/16x16/actions/process-stop.png</file>
|
||||
<file>icons/16x16/actions/go-home.png</file>
|
||||
<file>icons/16x16/actions/go-up.png</file>
|
||||
<file>icons/16x16/actions/mail-send-receive-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/view-fullscreen-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/actions/document-edit-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/emotes/face-cool.png</file>
|
||||
<file>icons/16x16/emotes/face-laugh-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/status/battery-caution-charging-symbolic.symbolic.png</file>
|
||||
<file>icons/16x16/categories/applications-other.png</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!--*- mode: xml -*-->
|
||||
<interface>
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
@@ -75,7 +76,8 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem"/>
|
||||
<object class="GtkSeparatorMenuItem">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="quit_item">
|
||||
@@ -172,7 +174,8 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorToolItem"/>
|
||||
<object class="GtkSeparatorToolItem">
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToolButton">
|
||||
@@ -196,6 +199,9 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
@@ -249,9 +255,16 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStatusbar" id="statusbar1"/>
|
||||
<object class="GtkStatusbar" id="statusbar1">
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
@@ -1,489 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* Authors:
|
||||
* - Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "demotaggedentry.h"
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtk-a11y.h>
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *box;
|
||||
GtkWidget *entry;
|
||||
} DemoTaggedEntryPrivate;
|
||||
|
||||
static void demo_tagged_entry_editable_init (GtkEditableInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (DemoTaggedEntry, demo_tagged_entry, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (DemoTaggedEntry)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, demo_tagged_entry_editable_init))
|
||||
|
||||
static void
|
||||
demo_tagged_entry_init (DemoTaggedEntry *entry)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_parent (priv->box, GTK_WIDGET (entry));
|
||||
|
||||
priv->entry = gtk_text_new ();
|
||||
gtk_widget_set_hexpand (priv->entry, TRUE);
|
||||
gtk_widget_set_vexpand (priv->entry, TRUE);
|
||||
gtk_widget_set_hexpand (priv->box, FALSE);
|
||||
gtk_widget_set_vexpand (priv->box, FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (priv->box), priv->entry);
|
||||
gtk_editable_init_delegate (GTK_EDITABLE (entry));
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_dispose (GObject *object)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (object);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
if (priv->entry)
|
||||
gtk_editable_finish_delegate (GTK_EDITABLE (entry));
|
||||
|
||||
g_clear_pointer (&priv->entry, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->box, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_finalize (GObject *object)
|
||||
{
|
||||
G_OBJECT_CLASS (demo_tagged_entry_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
if (gtk_editable_delegate_set_property (object, prop_id, value, pspec))
|
||||
return;
|
||||
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
if (gtk_editable_delegate_get_property (object, prop_id, value, pspec))
|
||||
return;
|
||||
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
gtk_widget_measure (priv->box, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
gtk_widget_size_allocate (priv->box,
|
||||
&(GtkAllocation) { 0, 0, width, height },
|
||||
baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
gtk_widget_grab_focus (priv->entry);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_class_init (DemoTaggedEntryClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = demo_tagged_entry_dispose;
|
||||
object_class->finalize = demo_tagged_entry_finalize;
|
||||
object_class->get_property = demo_tagged_entry_get_property;
|
||||
object_class->set_property = demo_tagged_entry_set_property;
|
||||
|
||||
widget_class->measure = demo_tagged_entry_measure;
|
||||
widget_class->size_allocate = demo_tagged_entry_size_allocate;
|
||||
widget_class->grab_focus = demo_tagged_entry_grab_focus;
|
||||
|
||||
gtk_editable_install_properties (object_class, 1);
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_ENTRY_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, "entry");
|
||||
}
|
||||
|
||||
static GtkEditable *
|
||||
demo_tagged_entry_get_delegate (GtkEditable *editable)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (editable);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
return GTK_EDITABLE (priv->entry);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_editable_init (GtkEditableInterface *iface)
|
||||
{
|
||||
iface->get_delegate = demo_tagged_entry_get_delegate;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
demo_tagged_entry_new (void)
|
||||
{
|
||||
return GTK_WIDGET (g_object_new (DEMO_TYPE_TAGGED_ENTRY, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (priv->box), tag);
|
||||
}
|
||||
|
||||
void
|
||||
demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag,
|
||||
GtkWidget *sibling)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
||||
|
||||
if (sibling == NULL)
|
||||
gtk_container_add (GTK_CONTAINER (priv->box), tag);
|
||||
else
|
||||
gtk_box_insert_child_after (GTK_BOX (priv->box), tag, sibling);
|
||||
}
|
||||
|
||||
void
|
||||
demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY (entry));
|
||||
|
||||
gtk_container_remove (GTK_CONTAINER (priv->box), tag);
|
||||
}
|
||||
|
||||
struct _DemoTaggedEntryTag
|
||||
{
|
||||
GtkWidget parent;
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
GtkWidget *button;
|
||||
|
||||
gboolean has_close_button;
|
||||
char *style;
|
||||
};
|
||||
|
||||
struct _DemoTaggedEntryTagClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_LABEL,
|
||||
PROP_HAS_CLOSE_BUTTON,
|
||||
};
|
||||
|
||||
enum {
|
||||
SIGNAL_CLICKED,
|
||||
SIGNAL_BUTTON_CLICKED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
on_released (GtkGestureClick *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoTaggedEntryTag *tag)
|
||||
{
|
||||
g_signal_emit (tag, signals[SIGNAL_CLICKED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_init (DemoTaggedEntryTag *tag)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
tag->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_parent (tag->box, GTK_WIDGET (tag));
|
||||
tag->label = gtk_label_new ("");
|
||||
gtk_container_add (GTK_CONTAINER (tag->box), tag->label);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
g_signal_connect (gesture, "released", G_CALLBACK (on_released), tag);
|
||||
gtk_widget_add_controller (GTK_WIDGET (tag), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/tagged_entry/tagstyle.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_dispose (GObject *object)
|
||||
{
|
||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
||||
|
||||
g_clear_pointer (&tag->box, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (demo_tagged_entry_tag_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_finalize (GObject *object)
|
||||
{
|
||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
||||
|
||||
g_clear_pointer (&tag->box, gtk_widget_unparent);
|
||||
g_clear_pointer (&tag->style, g_free);
|
||||
|
||||
G_OBJECT_CLASS (demo_tagged_entry_tag_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LABEL:
|
||||
demo_tagged_entry_tag_set_label (tag, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_HAS_CLOSE_BUTTON:
|
||||
demo_tagged_entry_tag_set_has_close_button (tag, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_LABEL:
|
||||
g_value_set_string (value, demo_tagged_entry_tag_get_label (tag));
|
||||
break;
|
||||
|
||||
case PROP_HAS_CLOSE_BUTTON:
|
||||
g_value_set_boolean (value, demo_tagged_entry_tag_get_has_close_button (tag));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (widget);
|
||||
|
||||
gtk_widget_measure (tag->box, orientation, for_size,
|
||||
minimum, natural,
|
||||
minimum_baseline, natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
DemoTaggedEntryTag *tag = DEMO_TAGGED_ENTRY_TAG (widget);
|
||||
|
||||
gtk_widget_size_allocate (tag->box,
|
||||
&(GtkAllocation) { 0, 0, width, height },
|
||||
baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
demo_tagged_entry_tag_class_init (DemoTaggedEntryTagClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->dispose = demo_tagged_entry_tag_dispose;
|
||||
object_class->finalize = demo_tagged_entry_tag_finalize;
|
||||
object_class->set_property = demo_tagged_entry_tag_set_property;
|
||||
object_class->get_property = demo_tagged_entry_tag_get_property;
|
||||
|
||||
widget_class->measure = demo_tagged_entry_tag_measure;
|
||||
widget_class->size_allocate = demo_tagged_entry_tag_size_allocate;
|
||||
|
||||
signals[SIGNAL_CLICKED] =
|
||||
g_signal_new ("clicked",
|
||||
DEMO_TYPE_TAGGED_ENTRY_TAG,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[SIGNAL_BUTTON_CLICKED] =
|
||||
g_signal_new ("button-clicked",
|
||||
DEMO_TYPE_TAGGED_ENTRY_TAG,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_class_install_property (object_class, PROP_LABEL,
|
||||
g_param_spec_string ("label", "Label", "Label",
|
||||
NULL, G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, PROP_HAS_CLOSE_BUTTON,
|
||||
g_param_spec_boolean ("has-close-button", "Has close button", "Whether this tag has a close button",
|
||||
FALSE, G_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "tag");
|
||||
}
|
||||
|
||||
DemoTaggedEntryTag *
|
||||
demo_tagged_entry_tag_new (const char *label)
|
||||
{
|
||||
return DEMO_TAGGED_ENTRY_TAG (g_object_new (DEMO_TYPE_TAGGED_ENTRY_TAG,
|
||||
"label", label,
|
||||
NULL));
|
||||
}
|
||||
|
||||
const char *
|
||||
demo_tagged_entry_tag_get_label (DemoTaggedEntryTag *tag)
|
||||
{
|
||||
g_return_val_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag), NULL);
|
||||
|
||||
return gtk_label_get_label (GTK_LABEL (tag->label));
|
||||
}
|
||||
|
||||
void
|
||||
demo_tagged_entry_tag_set_label (DemoTaggedEntryTag *tag,
|
||||
const char *label)
|
||||
{
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag));
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (tag->label), label);
|
||||
}
|
||||
|
||||
static void
|
||||
on_button_clicked (GtkButton *button,
|
||||
DemoTaggedEntryTag *tag)
|
||||
{
|
||||
g_signal_emit (tag, signals[SIGNAL_BUTTON_CLICKED], 0);
|
||||
}
|
||||
|
||||
void
|
||||
demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
|
||||
gboolean has_close_button)
|
||||
{
|
||||
g_return_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag));
|
||||
|
||||
if ((tag->button != NULL) == has_close_button)
|
||||
return;
|
||||
|
||||
if (!has_close_button && tag->button)
|
||||
{
|
||||
gtk_container_remove (GTK_CONTAINER (tag->box), tag->button);
|
||||
tag->button = NULL;
|
||||
}
|
||||
else if (has_close_button && tag->button == NULL)
|
||||
{
|
||||
GtkWidget *image;
|
||||
|
||||
image = gtk_image_new_from_icon_name ("window-close-symbolic");
|
||||
tag->button = gtk_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (tag->button), image);
|
||||
gtk_widget_set_halign (tag->button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (tag->button, GTK_ALIGN_CENTER);
|
||||
gtk_button_set_relief (GTK_BUTTON (tag->button), GTK_RELIEF_NONE);
|
||||
gtk_container_add (GTK_CONTAINER (tag->box), tag->button);
|
||||
g_signal_connect (tag->button, "clicked", G_CALLBACK (on_button_clicked), tag);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (tag), "has-close-button");
|
||||
}
|
||||
|
||||
gboolean
|
||||
demo_tagged_entry_tag_get_has_close_button (DemoTaggedEntryTag *tag)
|
||||
{
|
||||
g_return_val_if_fail (DEMO_IS_TAGGED_ENTRY_TAG (tag), FALSE);
|
||||
|
||||
return tag->button != NULL;
|
||||
}
|
@@ -1,89 +0,0 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* Authors:
|
||||
* - Matthias Clasen <mclasen@redhat.com>
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __DEMO_TAGGED_ENTRY_H__
|
||||
#define __DEMO_TAGGED_ENTRY_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define DEMO_TYPE_TAGGED_ENTRY (demo_tagged_entry_get_type ())
|
||||
#define DEMO_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntry))
|
||||
#define DEMO_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
|
||||
#define DEMO_IS_TAGGED_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY))
|
||||
#define DEMO_IS_TAGGED_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY))
|
||||
#define DEMO_TAGGED_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY, DemoTaggedEntryClass))
|
||||
|
||||
typedef struct _DemoTaggedEntry DemoTaggedEntry;
|
||||
typedef struct _DemoTaggedEntryClass DemoTaggedEntryClass;
|
||||
|
||||
struct _DemoTaggedEntry
|
||||
{
|
||||
GtkWidget parent;
|
||||
};
|
||||
|
||||
struct _DemoTaggedEntryClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
#define DEMO_TYPE_TAGGED_ENTRY_TAG (demo_tagged_entry_tag_get_type ())
|
||||
#define DEMO_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
|
||||
#define DEMO_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTag))
|
||||
#define DEMO_IS_TAGGED_ENTRY_TAG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG))
|
||||
#define DEMO_IS_TAGGED_ENTRY_TAG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), DEMO_TYPE_TAGGED_ENTRY_TAG))
|
||||
#define DEMO_TAGGED_ENTRY_TAG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), DEMO_TYPE_TAGGED_ENTRY_TAG, DemoTaggedEntryTagClass))
|
||||
|
||||
typedef struct _DemoTaggedEntryTag DemoTaggedEntryTag;
|
||||
typedef struct _DemoTaggedEntryTagClass DemoTaggedEntryTagClass;
|
||||
|
||||
|
||||
GType demo_tagged_entry_get_type (void) G_GNUC_CONST;
|
||||
GType demo_tagged_entry_tag_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget * demo_tagged_entry_new (void);
|
||||
|
||||
void demo_tagged_entry_add_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag);
|
||||
|
||||
void demo_tagged_entry_insert_tag_after (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag,
|
||||
GtkWidget *sibling);
|
||||
|
||||
void demo_tagged_entry_remove_tag (DemoTaggedEntry *entry,
|
||||
GtkWidget *tag);
|
||||
|
||||
DemoTaggedEntryTag *
|
||||
demo_tagged_entry_tag_new (const char *label);
|
||||
|
||||
const char * demo_tagged_entry_tag_get_label (DemoTaggedEntryTag *tag);
|
||||
|
||||
void demo_tagged_entry_tag_set_label (DemoTaggedEntryTag *tag,
|
||||
const char *label);
|
||||
|
||||
gboolean demo_tagged_entry_tag_get_has_close_button (DemoTaggedEntryTag *tag);
|
||||
|
||||
void demo_tagged_entry_tag_set_has_close_button (DemoTaggedEntryTag *tag,
|
||||
gboolean has_close_button);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __DEMO_TAGGED_ENTRY_H__ */
|
@@ -56,20 +56,20 @@ interactive_dialog_clicked (GtkButton *button,
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (content_area), hbox);
|
||||
|
||||
image = gtk_image_new_from_icon_name ("dialog-question");
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), image);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), table);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), table);
|
||||
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||
local_entry1 = gtk_entry_new ();
|
||||
gtk_editable_set_text (GTK_EDITABLE (local_entry1), gtk_editable_get_text (GTK_EDITABLE (entry1)));
|
||||
gtk_entry_set_text (GTK_ENTRY (local_entry1), gtk_entry_get_text (GTK_ENTRY (entry1)));
|
||||
gtk_grid_attach (GTK_GRID (table), local_entry1, 1, 0, 1, 1);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry1);
|
||||
|
||||
@@ -77,7 +77,7 @@ interactive_dialog_clicked (GtkButton *button,
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
|
||||
|
||||
local_entry2 = gtk_entry_new ();
|
||||
gtk_editable_set_text (GTK_EDITABLE (local_entry2), gtk_editable_get_text (GTK_EDITABLE (entry2)));
|
||||
gtk_entry_set_text (GTK_ENTRY (local_entry2), gtk_entry_get_text (GTK_ENTRY (entry2)));
|
||||
gtk_grid_attach (GTK_GRID (table), local_entry2, 1, 1, 1, 1);
|
||||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), local_entry2);
|
||||
|
||||
@@ -85,8 +85,8 @@ interactive_dialog_clicked (GtkButton *button,
|
||||
|
||||
if (response == GTK_RESPONSE_OK)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry1), gtk_editable_get_text (GTK_EDITABLE (local_entry1)));
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry2), gtk_editable_get_text (GTK_EDITABLE (local_entry2)));
|
||||
gtk_entry_set_text (GTK_ENTRY (entry1), gtk_entry_get_text (GTK_ENTRY (local_entry1)));
|
||||
gtk_entry_set_text (GTK_ENTRY (entry2), gtk_entry_get_text (GTK_ENTRY (local_entry2)));
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
@@ -123,29 +123,29 @@ do_dialog (GtkWidget *do_widget)
|
||||
|
||||
/* Standard message dialog */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
button = gtk_button_new_with_mnemonic ("_Message Dialog");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (message_dialog_clicked), NULL);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
|
||||
|
||||
/* Interactive dialog*/
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
|
||||
button = gtk_button_new_with_mnemonic ("_Interactive Dialog");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (interactive_dialog_clicked), NULL);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), vbox2);
|
||||
gtk_container_add (GTK_CONTAINER (vbox2), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox2);
|
||||
gtk_box_pack_start (GTK_BOX (vbox2), button);
|
||||
|
||||
table = gtk_grid_new ();
|
||||
gtk_grid_set_row_spacing (GTK_GRID (table), 4);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (table), 4);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), table);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), table);
|
||||
|
||||
label = gtk_label_new_with_mnemonic ("_Entry 1");
|
||||
gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
|
||||
|
@@ -196,10 +196,10 @@ edit_label_done (GtkWidget *entry, gpointer data)
|
||||
GtkWidget *label;
|
||||
int x, y;
|
||||
|
||||
gtk_fixed_get_child_position (GTK_FIXED (fixed), entry, &x, &y);
|
||||
gtk_container_child_get (GTK_CONTAINER (fixed), entry, "x", &x, "y", &y, NULL);
|
||||
|
||||
label = GTK_WIDGET (g_object_get_data (G_OBJECT (entry), "label"));
|
||||
gtk_label_set_text (GTK_LABEL (label), gtk_editable_get_text (GTK_EDITABLE (entry)));
|
||||
gtk_label_set_text (GTK_LABEL (label), gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||
|
||||
gtk_widget_destroy (entry);
|
||||
}
|
||||
@@ -210,7 +210,7 @@ edit_cb (GtkWidget *child)
|
||||
GtkWidget *fixed = gtk_widget_get_parent (child);
|
||||
int x, y;
|
||||
|
||||
gtk_fixed_get_child_position (GTK_FIXED (fixed), child, &x, &y);
|
||||
gtk_container_child_get (GTK_CONTAINER (fixed), child, "x", &x, "y", &y, NULL);
|
||||
|
||||
if (GTK_IS_LABEL (child))
|
||||
{
|
||||
@@ -218,7 +218,7 @@ edit_cb (GtkWidget *child)
|
||||
|
||||
g_object_set_data (G_OBJECT (entry), "label", child);
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), gtk_label_get_text (GTK_LABEL (child)));
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), gtk_label_get_text (GTK_LABEL (child)));
|
||||
g_signal_connect (entry, "activate", G_CALLBACK (edit_label_done), NULL);
|
||||
gtk_fixed_put (GTK_FIXED (fixed), entry, x, y);
|
||||
gtk_widget_grab_focus (entry);
|
||||
@@ -243,7 +243,7 @@ pressed_cb (GtkGesture *gesture,
|
||||
GtkWidget *child;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
child = gtk_widget_pick (widget, x, y, GTK_PICK_DEFAULT);
|
||||
child = gtk_widget_pick (widget, x, y);
|
||||
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
@@ -299,7 +299,7 @@ pressed_cb (GtkGesture *gesture,
|
||||
rect.height = 0;
|
||||
|
||||
gtk_menu_popup_at_rect (GTK_MENU (menu),
|
||||
gtk_native_get_surface (gtk_widget_get_native (widget)),
|
||||
gtk_widget_get_surface (widget),
|
||||
&rect,
|
||||
GDK_GRAVITY_NORTH_WEST,
|
||||
GDK_GRAVITY_NORTH_WEST,
|
||||
@@ -320,7 +320,7 @@ released_cb (GtkGesture *gesture,
|
||||
GtkWidget *child;
|
||||
|
||||
widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
|
||||
child = gtk_widget_pick (widget, x, y, 0);
|
||||
child = gtk_widget_pick (widget, x, y);
|
||||
|
||||
if (gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture)) == GDK_BUTTON_PRIMARY)
|
||||
{
|
||||
@@ -352,15 +352,14 @@ do_dnd (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
fixed = gtk_fixed_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), fixed);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), fixed);
|
||||
gtk_widget_set_hexpand (fixed, TRUE);
|
||||
gtk_widget_set_vexpand (fixed, TRUE);
|
||||
|
||||
multipress = gtk_gesture_click_new ();
|
||||
multipress = gtk_gesture_multi_press_new (fixed);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (multipress), 0);
|
||||
g_signal_connect (multipress, "pressed", G_CALLBACK (pressed_cb), NULL);
|
||||
g_signal_connect (multipress, "released", G_CALLBACK (released_cb), NULL);
|
||||
gtk_widget_add_controller (fixed, GTK_EVENT_CONTROLLER (multipress));
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/dnd/dnd.css");
|
||||
|
@@ -86,7 +86,7 @@ draw_brush (GtkWidget *widget,
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
gtk_widget_queue_draw (widget);
|
||||
gtk_widget_queue_draw_area (widget, update_rect.x, update_rect.y, update_rect.width, update_rect.height);
|
||||
}
|
||||
|
||||
static double start_x;
|
||||
@@ -208,12 +208,12 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Checkerboard pattern</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_widget_set_vexpand (frame, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
||||
@@ -228,12 +228,12 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"<u>Scribble area</u>");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_widget_set_vexpand (frame, TRUE);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 100);
|
||||
@@ -244,14 +244,13 @@ do_drawingarea (GtkWidget *do_widget)
|
||||
g_signal_connect (da, "size-allocate",
|
||||
G_CALLBACK (scribble_size_allocate), NULL);
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
drag = gtk_gesture_drag_new (da);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (drag), GDK_BUTTON_PRIMARY);
|
||||
gtk_widget_add_controller (da, GTK_EVENT_CONTROLLER (drag));
|
||||
g_object_set_data_full (G_OBJECT (da), "drag", drag, g_object_unref);
|
||||
|
||||
g_signal_connect (drag, "drag-begin", G_CALLBACK (drag_begin), da);
|
||||
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_update), da);
|
||||
g_signal_connect (drag, "drag-end", G_CALLBACK (drag_end), da);
|
||||
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -356,7 +356,7 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
g_object_set (vbox, "margin", 5, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (vbox),
|
||||
gtk_box_pack_start (GTK_BOX (vbox),
|
||||
gtk_label_new ("Shopping list (you can edit the cells!)"));
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
@@ -365,7 +365,7 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), sw);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), sw);
|
||||
|
||||
/* create models */
|
||||
items_model = create_items_model ();
|
||||
@@ -387,17 +387,17 @@ do_editable_cells (GtkWidget *do_widget)
|
||||
/* some buttons */
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
|
||||
gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), hbox);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox);
|
||||
|
||||
button = gtk_button_new_with_label ("Add item");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (add_item), treeview);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
|
||||
button = gtk_button_new_with_label ("Remove item");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (remove_item), treeview);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), button);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), button);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 320, 200);
|
||||
}
|
||||
|
@@ -34,19 +34,19 @@ do_entry_buffer (GtkWidget *do_widget)
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"Entries share a buffer. Typing in one is reflected in the other.");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
/* Create a buffer */
|
||||
buffer = gtk_entry_buffer_new (NULL, 0);
|
||||
|
||||
/* Create our first entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), entry);
|
||||
|
||||
/* Create the second entry */
|
||||
entry = gtk_entry_new_with_buffer (buffer);
|
||||
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), entry);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
@@ -60,11 +60,11 @@ do_entry_completion (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), "Completion demo, try writing <b>total</b> or <b>gnome</b> for example.");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), label);
|
||||
|
||||
/* Create our entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_container_add (GTK_CONTAINER (vbox), entry);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), entry);
|
||||
|
||||
/* Create the completion object */
|
||||
completion = gtk_entry_completion_new ();
|
||||
|
668
demos/gtk-demo/event_axes.c
Normal file
@@ -0,0 +1,668 @@
|
||||
/* Touch and Drawing Tablets
|
||||
*
|
||||
* Demonstrates advanced handling of event information from exotic
|
||||
* input devices.
|
||||
*
|
||||
* On one hand, this snippet demonstrates management of drawing tablets,
|
||||
* those contain additional information for the pointer other than
|
||||
* X/Y coordinates. Tablet pads events are mapped to actions, which
|
||||
* are both defined and interpreted by the application.
|
||||
*
|
||||
* Input axes are dependent on hardware devices, on linux/unix you
|
||||
* can see the device axes through xinput list <device>. Each time
|
||||
* a different hardware device is used to move the pointer, the
|
||||
* master device will be updated to match the axes it provides,
|
||||
* these changes can be tracked through GdkDevice::changed, or
|
||||
* checking gdk_event_get_source_device().
|
||||
*
|
||||
* On the other hand, this demo handles basic multitouch events,
|
||||
* each event coming from an specific touchpoint will contain a
|
||||
* GdkEventSequence that's unique for its lifetime, so multiple
|
||||
* touchpoints can be tracked.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef struct {
|
||||
GdkDevice *last_source;
|
||||
GdkDeviceTool *last_tool;
|
||||
gdouble *axes;
|
||||
GdkRGBA color;
|
||||
gdouble x;
|
||||
gdouble y;
|
||||
} AxesInfo;
|
||||
|
||||
typedef struct {
|
||||
GHashTable *pointer_info; /* GdkDevice -> AxesInfo */
|
||||
GHashTable *touch_info; /* GdkEventSequence -> AxesInfo */
|
||||
} EventData;
|
||||
|
||||
const gchar *colors[] = {
|
||||
"black",
|
||||
"orchid",
|
||||
"fuchsia",
|
||||
"indigo",
|
||||
"thistle",
|
||||
"sienna",
|
||||
"azure",
|
||||
"plum",
|
||||
"lime",
|
||||
"navy",
|
||||
"maroon",
|
||||
"burlywood"
|
||||
};
|
||||
|
||||
static GtkPadActionEntry pad_actions[] = {
|
||||
{ GTK_PAD_ACTION_BUTTON, 1, -1, N_("Nuclear strike"), "pad.nuke" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 2, -1, N_("Release siberian methane reserves"), "pad.heat" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 3, -1, N_("Release solar flare"), "pad.fry" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 4, -1, N_("De-stabilize Oort cloud"), "pad.fall" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 5, -1, N_("Ignite WR-104"), "pad.burst" },
|
||||
{ GTK_PAD_ACTION_BUTTON, 6, -1, N_("Lart whoever asks about this button"), "pad.lart" },
|
||||
{ GTK_PAD_ACTION_RING, -1, -1, N_("Earth axial tilt"), "pad.tilt" },
|
||||
{ GTK_PAD_ACTION_STRIP, -1, -1, N_("Extent of weak nuclear force"), "pad.dissolve" },
|
||||
};
|
||||
|
||||
static const gchar *pad_action_results[] = {
|
||||
"☢",
|
||||
"♨",
|
||||
"☼",
|
||||
"☄",
|
||||
"⚡",
|
||||
"💫",
|
||||
"◑",
|
||||
"⚛"
|
||||
};
|
||||
|
||||
static guint cur_color = 0;
|
||||
static guint pad_action_timeout_id = 0;
|
||||
|
||||
static AxesInfo *
|
||||
axes_info_new (void)
|
||||
{
|
||||
AxesInfo *info;
|
||||
|
||||
info = g_new0 (AxesInfo, 1);
|
||||
gdk_rgba_parse (&info->color, colors[cur_color]);
|
||||
|
||||
cur_color = (cur_color + 1) % G_N_ELEMENTS (colors);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static EventData *
|
||||
event_data_new (void)
|
||||
{
|
||||
EventData *data;
|
||||
|
||||
data = g_new0 (EventData, 1);
|
||||
data->pointer_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
data->touch_info = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
event_data_free (EventData *data)
|
||||
{
|
||||
g_hash_table_destroy (data->pointer_info);
|
||||
g_hash_table_destroy (data->touch_info);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_axes_from_event (GdkEvent *event,
|
||||
EventData *data)
|
||||
{
|
||||
GdkDevice *device, *source_device;
|
||||
GdkEventSequence *sequence;
|
||||
GdkDeviceTool *tool;
|
||||
GdkEventType type;
|
||||
gdouble x, y;
|
||||
AxesInfo *info;
|
||||
|
||||
device = gdk_event_get_device (event);
|
||||
source_device = gdk_event_get_source_device (event);
|
||||
sequence = gdk_event_get_event_sequence (event);
|
||||
tool = gdk_event_get_device_tool (event);
|
||||
type = gdk_event_get_event_type (event);
|
||||
|
||||
if (type == GDK_TOUCH_END ||
|
||||
type == GDK_TOUCH_CANCEL)
|
||||
{
|
||||
g_hash_table_remove (data->touch_info, sequence);
|
||||
return;
|
||||
}
|
||||
else if (type == GDK_LEAVE_NOTIFY)
|
||||
{
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!source_device)
|
||||
return;
|
||||
|
||||
if (!sequence)
|
||||
{
|
||||
info = g_hash_table_lookup (data->pointer_info, device);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->pointer_info, device, info);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info = g_hash_table_lookup (data->touch_info, sequence);
|
||||
|
||||
if (!info)
|
||||
{
|
||||
info = axes_info_new ();
|
||||
g_hash_table_insert (data->touch_info, sequence, info);
|
||||
}
|
||||
}
|
||||
|
||||
if (info->last_source != source_device)
|
||||
info->last_source = source_device;
|
||||
|
||||
if (info->last_tool != tool)
|
||||
info->last_tool = tool;
|
||||
|
||||
g_clear_pointer (&info->axes, g_free);
|
||||
|
||||
if (type == GDK_TOUCH_BEGIN ||
|
||||
type == GDK_TOUCH_UPDATE)
|
||||
{
|
||||
gboolean emulating_pointer;
|
||||
|
||||
gdk_event_get_touch_emulating_pointer (event, &emulating_pointer);
|
||||
if (sequence && emulating_pointer)
|
||||
g_hash_table_remove (data->pointer_info, device);
|
||||
}
|
||||
if (type == GDK_MOTION_NOTIFY ||
|
||||
type == GDK_BUTTON_PRESS ||
|
||||
type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
gdouble *axes;
|
||||
guint n_axes;
|
||||
|
||||
gdk_event_get_axes (event, &axes, &n_axes);
|
||||
info->axes = g_memdup (axes, sizeof (double) * n_axes);
|
||||
}
|
||||
|
||||
if (gdk_event_get_coords (event, &x, &y))
|
||||
{
|
||||
info->x = x;
|
||||
info->y = y;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
event_cb (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer user_data)
|
||||
{
|
||||
update_axes_from_event (event, user_data);
|
||||
gtk_widget_queue_draw (widget);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
render_arrow (cairo_t *cr,
|
||||
gdouble x_diff,
|
||||
gdouble y_diff,
|
||||
const gchar *label)
|
||||
{
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_new_path (cr);
|
||||
cairo_move_to (cr, 0, 0);
|
||||
cairo_line_to (cr, x_diff, y_diff);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, x_diff, y_diff);
|
||||
cairo_show_text (cr, label);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_axes_info (cairo_t *cr,
|
||||
AxesInfo *info,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
gdouble pressure, tilt_x, tilt_y, distance, wheel, rotation, slider;
|
||||
GdkAxisFlags axes = gdk_device_get_axes (info->last_source);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_line_width (cr, 1);
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
|
||||
cairo_move_to (cr, 0, info->y);
|
||||
cairo_line_to (cr, width, info->y);
|
||||
cairo_move_to (cr, info->x, 0);
|
||||
cairo_line_to (cr, info->x, height);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_translate (cr, info->x, info->y);
|
||||
|
||||
if (!info->axes)
|
||||
{
|
||||
cairo_restore (cr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_PRESSURE)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_PRESSURE,
|
||||
&pressure);
|
||||
|
||||
pattern = cairo_pattern_create_radial (0, 0, 0, 0, 0, 100);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, pressure, 1, 0, 0, pressure);
|
||||
cairo_pattern_add_color_stop_rgba (pattern, 1, 0, 0, 1, 0);
|
||||
|
||||
cairo_set_source (cr, pattern);
|
||||
|
||||
cairo_arc (cr, 0, 0, 100, 0, 2 * G_PI);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_pattern_destroy (pattern);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_XTILT &&
|
||||
axes & GDK_AXIS_FLAG_YTILT)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_XTILT,
|
||||
&tilt_x);
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_YTILT,
|
||||
&tilt_y);
|
||||
|
||||
render_arrow (cr, tilt_x * 100, tilt_y * 100, "Tilt");
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_DISTANCE)
|
||||
{
|
||||
double dashes[] = { 5.0, 5.0 };
|
||||
cairo_text_extents_t extents;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_DISTANCE,
|
||||
&distance);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, distance * 100, 0);
|
||||
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
|
||||
cairo_set_dash (cr, dashes, 2, 0.0);
|
||||
cairo_arc (cr, 0, 0, distance * 100, 0, 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -distance * 100);
|
||||
cairo_text_extents (cr, "Distance", &extents);
|
||||
cairo_rel_move_to (cr, -extents.width / 2, 0);
|
||||
cairo_show_text (cr, "Distance");
|
||||
|
||||
cairo_move_to (cr, 0, 0);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_WHEEL)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_WHEEL,
|
||||
&wheel);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_set_source_rgba (cr, 0, 0, 0, 0.5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, wheel * 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_ROTATION)
|
||||
{
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_ROTATION,
|
||||
&rotation);
|
||||
rotation *= 2 * G_PI;
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_rotate (cr, - G_PI / 2);
|
||||
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
|
||||
cairo_set_line_width (cr, 5);
|
||||
|
||||
cairo_new_sub_path (cr);
|
||||
cairo_arc (cr, 0, 0, 100, 0, rotation);
|
||||
cairo_stroke (cr);
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
if (axes & GDK_AXIS_FLAG_SLIDER)
|
||||
{
|
||||
cairo_pattern_t *pattern, *mask;
|
||||
|
||||
gdk_device_get_axis (info->last_source, info->axes, GDK_AXIS_SLIDER,
|
||||
&slider);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_move_to (cr, 0, -10);
|
||||
cairo_rel_line_to (cr, 0, -50);
|
||||
cairo_rel_line_to (cr, 10, 0);
|
||||
cairo_rel_line_to (cr, -5, 50);
|
||||
cairo_close_path (cr);
|
||||
|
||||
cairo_clip_preserve (cr);
|
||||
|
||||
pattern = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 0, 0, 1, 0);
|
||||
cairo_pattern_add_color_stop_rgb (pattern, 1, 1, 0, 0);
|
||||
cairo_set_source (cr, pattern);
|
||||
cairo_pattern_destroy (pattern);
|
||||
|
||||
mask = cairo_pattern_create_linear (0, -10, 0, -60);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 0, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 1);
|
||||
cairo_pattern_add_color_stop_rgba (mask, slider, 0, 0, 0, 0);
|
||||
cairo_pattern_add_color_stop_rgba (mask, 1, 0, 0, 0, 0);
|
||||
cairo_mask (cr, mask);
|
||||
cairo_pattern_destroy (mask);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
tool_type_to_string (GdkDeviceToolType tool_type)
|
||||
{
|
||||
switch (tool_type)
|
||||
{
|
||||
case GDK_DEVICE_TOOL_TYPE_PEN:
|
||||
return "Pen";
|
||||
case GDK_DEVICE_TOOL_TYPE_ERASER:
|
||||
return "Eraser";
|
||||
case GDK_DEVICE_TOOL_TYPE_BRUSH:
|
||||
return "Brush";
|
||||
case GDK_DEVICE_TOOL_TYPE_PENCIL:
|
||||
return "Pencil";
|
||||
case GDK_DEVICE_TOOL_TYPE_AIRBRUSH:
|
||||
return "Airbrush";
|
||||
case GDK_DEVICE_TOOL_TYPE_MOUSE:
|
||||
return "Mouse";
|
||||
case GDK_DEVICE_TOOL_TYPE_LENS:
|
||||
return "Lens cursor";
|
||||
case GDK_DEVICE_TOOL_TYPE_UNKNOWN:
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_device_info (GtkWidget *widget,
|
||||
cairo_t *cr,
|
||||
GdkEventSequence *sequence,
|
||||
gint *y,
|
||||
AxesInfo *info)
|
||||
{
|
||||
PangoLayout *layout;
|
||||
GString *string;
|
||||
gint height;
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
string = g_string_new (NULL);
|
||||
g_string_append_printf (string, "Source: %s",
|
||||
gdk_device_get_name (info->last_source));
|
||||
|
||||
if (sequence)
|
||||
g_string_append_printf (string, "\nSequence: %d",
|
||||
GPOINTER_TO_UINT (sequence));
|
||||
|
||||
if (info->last_tool)
|
||||
{
|
||||
const gchar *tool_type;
|
||||
guint64 serial;
|
||||
|
||||
tool_type = tool_type_to_string (gdk_device_tool_get_tool_type (info->last_tool));
|
||||
serial = gdk_device_tool_get_serial (info->last_tool);
|
||||
g_string_append_printf (string, "\nTool: %s", tool_type);
|
||||
|
||||
if (serial != 0)
|
||||
g_string_append_printf (string, ", Serial: %lx", serial);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 10, *y);
|
||||
layout = gtk_widget_create_pango_layout (widget, string->str);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
cairo_stroke (cr);
|
||||
|
||||
pango_layout_get_pixel_size (layout, NULL, &height);
|
||||
|
||||
gdk_cairo_set_source_rgba (cr, &info->color);
|
||||
cairo_set_line_width (cr, 10);
|
||||
cairo_move_to (cr, 0, *y);
|
||||
|
||||
*y = *y + height;
|
||||
cairo_line_to (cr, 0, *y);
|
||||
cairo_stroke (cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
g_object_unref (layout);
|
||||
g_string_free (string, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_cb (GtkDrawingArea *da,
|
||||
cairo_t *cr,
|
||||
int width,
|
||||
int height,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (da);
|
||||
EventData *data = user_data;
|
||||
AxesInfo *info;
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
gint y = 0;
|
||||
|
||||
/* Draw Abs info */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_axes_info (cr, info, width, height);
|
||||
}
|
||||
|
||||
/* Draw name, color legend and misc data */
|
||||
g_hash_table_iter_init (&iter, data->pointer_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, NULL, &y, info);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, data->touch_info);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
info = value;
|
||||
draw_device_info (widget, cr, key, &y, info);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_text (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
gchar *markup = NULL;
|
||||
|
||||
if (text)
|
||||
markup = g_strdup_printf ("<span font='48.0'>%s</span>", text);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
g_free (markup);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
reset_label_text_timeout_cb (gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
|
||||
update_label_text (label, NULL);
|
||||
pad_action_timeout_id = 0;
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_label_and_timeout (GtkWidget *label,
|
||||
const gchar *text)
|
||||
{
|
||||
if (pad_action_timeout_id)
|
||||
g_source_remove (pad_action_timeout_id);
|
||||
|
||||
update_label_text (label, text);
|
||||
pad_action_timeout_id = g_timeout_add (200, reset_label_text_timeout_cb, label);
|
||||
}
|
||||
|
||||
static void
|
||||
on_action_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *label = user_data;
|
||||
const gchar *result;
|
||||
gchar *str;
|
||||
|
||||
result = g_object_get_data (G_OBJECT (action), "action-result");
|
||||
|
||||
if (!parameter)
|
||||
update_label_and_timeout (label, result);
|
||||
else
|
||||
{
|
||||
str = g_strdup_printf ("%s %.2f", result, g_variant_get_double (parameter));
|
||||
update_label_and_timeout (label, str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_pad_controller (GtkWidget *window,
|
||||
GtkWidget *label)
|
||||
{
|
||||
GtkPadController *pad_controller;
|
||||
GSimpleActionGroup *action_group;
|
||||
GSimpleAction *action;
|
||||
gint i;
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
pad_controller = gtk_pad_controller_new (GTK_WINDOW (window),
|
||||
G_ACTION_GROUP (action_group),
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (pad_actions); i++)
|
||||
{
|
||||
if (pad_actions[i].type == GTK_PAD_ACTION_BUTTON)
|
||||
{
|
||||
action = g_simple_action_new (pad_actions[i].action_name, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
action = g_simple_action_new_stateful (pad_actions[i].action_name,
|
||||
G_VARIANT_TYPE_DOUBLE, NULL);
|
||||
}
|
||||
|
||||
g_signal_connect (action, "activate",
|
||||
G_CALLBACK (on_action_activate), label);
|
||||
g_object_set_data (G_OBJECT (action), "action-result",
|
||||
(gpointer) pad_action_results[i]);
|
||||
g_action_map_add_action (G_ACTION_MAP (action_group), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
gtk_pad_controller_set_action_entries (pad_controller, pad_actions,
|
||||
G_N_ELEMENTS (pad_actions));
|
||||
g_object_set_data_full (G_OBJECT (window), "pad-controller",
|
||||
pad_controller, g_object_unref);
|
||||
|
||||
g_object_unref (action_group);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_event_axes (GtkWidget *toplevel)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
EventData *event_data;
|
||||
GtkWidget *label;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *da;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Touch and Drawing Tablets");
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_widget_set_support_multidevice (window, TRUE);
|
||||
|
||||
event_data = event_data_new ();
|
||||
g_object_set_data_full (G_OBJECT (window), "gtk-demo-event-data",
|
||||
event_data, (GDestroyNotify) event_data_free);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (da), 400);
|
||||
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), draw_cb, event_data, NULL);
|
||||
gtk_widget_set_can_focus (da, TRUE);
|
||||
gtk_widget_grab_focus (da);
|
||||
|
||||
g_signal_connect (da, "event",
|
||||
G_CALLBACK (event_cb), event_data);
|
||||
|
||||
label = gtk_label_new ("");
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
|
||||
|
||||
overlay = gtk_overlay_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), overlay);
|
||||
gtk_container_add (GTK_CONTAINER (overlay), da);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), label);
|
||||
|
||||
init_pad_controller (da, label);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -31,14 +31,13 @@ do_expander (GtkWidget *do_widget)
|
||||
GtkWidget *toplevel;
|
||||
GtkWidget *area;
|
||||
GtkWidget *expander;
|
||||
GtkWidget *label;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *tv;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
|
||||
toplevel = gtk_widget_get_toplevel (do_widget);
|
||||
window = gtk_message_dialog_new_with_markup (GTK_WINDOW (toplevel),
|
||||
0,
|
||||
GTK_MESSAGE_ERROR,
|
||||
@@ -51,19 +50,13 @@ do_expander (GtkWidget *do_widget)
|
||||
|
||||
area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window));
|
||||
|
||||
label = gtk_widget_get_last_child (area);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), FALSE);
|
||||
gtk_widget_set_vexpand (label, FALSE);
|
||||
|
||||
expander = gtk_expander_new ("Details:");
|
||||
gtk_widget_set_vexpand (expander, TRUE);
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), 100);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (sw), TRUE);
|
||||
|
||||
tv = gtk_text_view_new ();
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
|
||||
@@ -80,7 +73,7 @@ do_expander (GtkWidget *do_widget)
|
||||
"resize the window. Do it already !", -1);
|
||||
gtk_container_add (GTK_CONTAINER (sw), tv);
|
||||
gtk_container_add (GTK_CONTAINER (expander), sw);
|
||||
gtk_container_add (GTK_CONTAINER (area), expander);
|
||||
gtk_box_pack_end (GTK_BOX (area), expander);
|
||||
g_signal_connect (expander, "notify::expanded",
|
||||
G_CALLBACK (expander_cb), window);
|
||||
|
||||
|
@@ -1,9 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
<!-- column-name width -->
|
||||
<column type="gint"/>
|
||||
<!-- column-name height -->
|
||||
<column type="gint"/>
|
||||
</columns>
|
||||
<data>
|
||||
@@ -40,16 +43,16 @@
|
||||
<property name="label" translatable="yes">Original</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<accessibility>
|
||||
<relation type="label-for" target="treeview1"/>
|
||||
</accessibility>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview1">
|
||||
@@ -84,11 +87,11 @@
|
||||
<accessibility>
|
||||
<relation type="labelled-by" target="label1"/>
|
||||
</accessibility>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview2">
|
||||
@@ -135,43 +138,43 @@
|
||||
<accessibility>
|
||||
<relation type="labelled-by" target="label2"/>
|
||||
</accessibility>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label2">
|
||||
<property name="label" translatable="yes">Computed Columns</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<accessibility>
|
||||
<relation type="label-for" target="treeview2"/>
|
||||
</accessibility>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label3">
|
||||
<property name="label" translatable="yes">Filtered</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
<accessibility>
|
||||
<relation type="label-for" target="treeview3"/>
|
||||
</accessibility>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="treeview3">
|
||||
@@ -200,11 +203,11 @@
|
||||
<accessibility>
|
||||
<relation type="labelled-by" target="label3"/>
|
||||
</accessibility>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
@@ -8,304 +8,165 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "gtkfishbowl.h"
|
||||
#include "gtkgears.h"
|
||||
|
||||
const char *const css =
|
||||
".blurred-button {"
|
||||
" box-shadow: 0px 0px 5px 10px rgba(0, 0, 0, 0.5);"
|
||||
"}"
|
||||
"";
|
||||
GtkWidget *allow_changes;
|
||||
|
||||
char **icon_names = NULL;
|
||||
gsize n_icon_names = 0;
|
||||
#define N_STATS 5
|
||||
|
||||
static void
|
||||
init_icon_names (GtkIconTheme *theme)
|
||||
{
|
||||
GPtrArray *icons;
|
||||
GList *l, *icon_list;
|
||||
#define STATS_UPDATE_TIME G_USEC_PER_SEC
|
||||
|
||||
if (icon_names)
|
||||
return;
|
||||
typedef struct _Stats Stats;
|
||||
struct _Stats {
|
||||
gint64 last_stats;
|
||||
gint64 last_frame;
|
||||
gint last_suggestion;
|
||||
guint frame_counter_max;
|
||||
|
||||
icon_list = gtk_icon_theme_list_icons (theme, NULL);
|
||||
icons = g_ptr_array_new ();
|
||||
|
||||
for (l = icon_list; l; l = l->next)
|
||||
{
|
||||
if (g_str_has_suffix (l->data, "symbolic"))
|
||||
continue;
|
||||
|
||||
g_ptr_array_add (icons, g_strdup (l->data));
|
||||
}
|
||||
|
||||
n_icon_names = icons->len;
|
||||
g_ptr_array_add (icons, NULL); /* NULL-terminate the array */
|
||||
icon_names = (char **) g_ptr_array_free (icons, FALSE);
|
||||
|
||||
/* don't free strings, we assigned them to the array */
|
||||
g_list_free_full (icon_list, g_free);
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_random_icon_name (GtkIconTheme *theme)
|
||||
{
|
||||
init_icon_names (theme);
|
||||
|
||||
return icon_names[g_random_int_range(0, n_icon_names)];
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
create_icon (void)
|
||||
{
|
||||
GtkWidget *image;
|
||||
|
||||
image = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()));
|
||||
gtk_image_set_icon_size (GTK_IMAGE (image), GTK_ICON_SIZE_LARGE);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_button (void)
|
||||
{
|
||||
return gtk_button_new_with_label ("Button");
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_blurred_button (void)
|
||||
{
|
||||
GtkWidget *w = gtk_button_new ();
|
||||
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (w), "blurred-button");
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_font_button (void)
|
||||
{
|
||||
return gtk_font_button_new ();
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_level_bar (void)
|
||||
{
|
||||
GtkWidget *w = gtk_level_bar_new_for_interval (0, 100);
|
||||
|
||||
gtk_level_bar_set_value (GTK_LEVEL_BAR (w), 50);
|
||||
|
||||
/* Force them to be a bit larger */
|
||||
gtk_widget_set_size_request (w, 200, -1);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_spinner (void)
|
||||
{
|
||||
GtkWidget *w = gtk_spinner_new ();
|
||||
|
||||
gtk_spinner_start (GTK_SPINNER (w));
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_spinbutton (void)
|
||||
{
|
||||
GtkWidget *w = gtk_spin_button_new_with_range (0, 10, 1);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_label (void)
|
||||
{
|
||||
GtkWidget *w = gtk_label_new ("pLorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
|
||||
|
||||
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_video (void)
|
||||
{
|
||||
GtkMediaStream *stream = gtk_media_file_new_for_resource ("/images/gtk-logo.webm");
|
||||
GtkWidget *w = gtk_picture_new_for_paintable (GDK_PAINTABLE (stream));
|
||||
|
||||
gtk_widget_set_size_request (w, 64, 64);
|
||||
gtk_media_stream_set_loop (stream, TRUE);
|
||||
gtk_media_stream_play (stream);
|
||||
g_object_unref (stream);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_gears (void)
|
||||
{
|
||||
GtkWidget *w = gtk_gears_new ();
|
||||
|
||||
gtk_widget_set_size_request (w, 100, 100);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_switch (void)
|
||||
{
|
||||
GtkWidget *w = gtk_switch_new ();
|
||||
|
||||
gtk_switch_set_state (GTK_SWITCH (w), TRUE);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static void
|
||||
mapped (GtkWidget *w)
|
||||
{
|
||||
gtk_menu_button_popup (GTK_MENU_BUTTON (w));
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_menu_button (void)
|
||||
{
|
||||
GtkWidget *w = gtk_menu_button_new ();
|
||||
GtkWidget *popover = gtk_popover_new (NULL);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (popover), gtk_button_new_with_label ("Hey!"));
|
||||
gtk_popover_set_autohide (GTK_POPOVER (popover), FALSE);
|
||||
gtk_menu_button_set_popover (GTK_MENU_BUTTON (w), popover);
|
||||
g_signal_connect (w, "map", G_CALLBACK (mapped), NULL);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *name;
|
||||
GtkWidget * (*create_func) (void);
|
||||
} widget_types[] = {
|
||||
{ "Icon", create_icon },
|
||||
{ "Button", create_button },
|
||||
{ "Blurbutton", create_blurred_button },
|
||||
{ "Fontbutton", create_font_button },
|
||||
{ "Levelbar", create_level_bar },
|
||||
{ "Label", create_label },
|
||||
{ "Spinner", create_spinner },
|
||||
{ "Spinbutton", create_spinbutton },
|
||||
{ "Video", create_video },
|
||||
{ "Gears", create_gears },
|
||||
{ "Switch", create_switch },
|
||||
{ "Menubutton", create_menu_button },
|
||||
guint stats_index;
|
||||
guint frame_counter[N_STATS];
|
||||
guint item_counter[N_STATS];
|
||||
};
|
||||
|
||||
static int selected_widget_type = -1;
|
||||
static const int N_WIDGET_TYPES = G_N_ELEMENTS (widget_types);
|
||||
static Stats *
|
||||
get_stats (GtkWidget *widget)
|
||||
{
|
||||
static GQuark stats_quark = 0;
|
||||
Stats *stats;
|
||||
|
||||
if (G_UNLIKELY (stats_quark == 0))
|
||||
stats_quark = g_quark_from_static_string ("stats");
|
||||
|
||||
stats = g_object_get_qdata (G_OBJECT (widget), stats_quark);
|
||||
if (stats == NULL)
|
||||
{
|
||||
stats = g_new0 (Stats, 1);
|
||||
g_object_set_qdata_full (G_OBJECT (widget), stats_quark, stats, g_free);
|
||||
stats->last_frame = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
stats->last_stats = stats->last_frame;
|
||||
}
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
static void
|
||||
set_widget_type (GtkFishbowl *fishbowl,
|
||||
int widget_type_index)
|
||||
do_stats (GtkWidget *widget,
|
||||
GtkWidget *info_label,
|
||||
gint *suggested_change)
|
||||
{
|
||||
GtkWidget *window, *headerbar;
|
||||
Stats *stats;
|
||||
gint64 frame_time;
|
||||
|
||||
if (widget_type_index == selected_widget_type)
|
||||
return;
|
||||
stats = get_stats (widget);
|
||||
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
|
||||
selected_widget_type = widget_type_index;
|
||||
if (stats->last_stats + STATS_UPDATE_TIME < frame_time)
|
||||
{
|
||||
char *new_label;
|
||||
guint i, n_frames;
|
||||
|
||||
gtk_fishbowl_set_creation_func (fishbowl,
|
||||
widget_types[selected_widget_type].create_func);
|
||||
n_frames = 0;
|
||||
for (i = 0; i < N_STATS; i++)
|
||||
{
|
||||
n_frames += stats->frame_counter[i];
|
||||
}
|
||||
|
||||
new_label = g_strdup_printf ("icons - %.1f fps",
|
||||
(double) G_USEC_PER_SEC * n_frames
|
||||
/ (N_STATS * STATS_UPDATE_TIME));
|
||||
gtk_label_set_label (GTK_LABEL (info_label), new_label);
|
||||
g_free (new_label);
|
||||
|
||||
window = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (fishbowl)));
|
||||
headerbar = gtk_window_get_titlebar (GTK_WINDOW (window));
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (headerbar),
|
||||
widget_types[selected_widget_type].name);
|
||||
if (stats->frame_counter[stats->stats_index] >= 19 * stats->frame_counter_max / 20)
|
||||
{
|
||||
if (stats->last_suggestion > 0)
|
||||
stats->last_suggestion *= 2;
|
||||
else
|
||||
stats->last_suggestion = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stats->last_suggestion < 0)
|
||||
stats->last_suggestion--;
|
||||
else
|
||||
stats->last_suggestion = -1;
|
||||
stats->last_suggestion = MAX (stats->last_suggestion, 1 - (int) stats->item_counter[stats->stats_index]);
|
||||
}
|
||||
|
||||
stats->stats_index = (stats->stats_index + 1) % N_STATS;
|
||||
stats->frame_counter[stats->stats_index] = 0;
|
||||
stats->item_counter[stats->stats_index] = stats->item_counter[(stats->stats_index + N_STATS - 1) % N_STATS];
|
||||
stats->last_stats = frame_time;
|
||||
|
||||
if (suggested_change)
|
||||
*suggested_change = stats->last_suggestion;
|
||||
else
|
||||
stats->last_suggestion = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (suggested_change)
|
||||
*suggested_change = 0;
|
||||
}
|
||||
|
||||
stats->last_frame = frame_time;
|
||||
stats->frame_counter[stats->stats_index]++;
|
||||
stats->frame_counter_max = MAX (stats->frame_counter_max, stats->frame_counter[stats->stats_index]);
|
||||
}
|
||||
|
||||
void
|
||||
next_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
static void
|
||||
stats_update (GtkWidget *widget)
|
||||
{
|
||||
GtkFishbowl *fishbowl = user_data;
|
||||
int new_index;
|
||||
Stats *stats;
|
||||
|
||||
if (selected_widget_type + 1 >= N_WIDGET_TYPES)
|
||||
new_index = 0;
|
||||
else
|
||||
new_index = selected_widget_type + 1;
|
||||
stats = get_stats (widget);
|
||||
|
||||
set_widget_type (fishbowl, new_index);
|
||||
stats->item_counter[stats->stats_index] = gtk_fishbowl_get_count (GTK_FISHBOWL (widget));
|
||||
}
|
||||
|
||||
void
|
||||
prev_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
static gboolean
|
||||
move_fish (GtkWidget *bowl,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer info_label)
|
||||
{
|
||||
GtkFishbowl *fishbowl = user_data;
|
||||
int new_index;
|
||||
gint suggested_change = 0;
|
||||
|
||||
do_stats (bowl,
|
||||
info_label,
|
||||
!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (allow_changes)) ? &suggested_change : NULL);
|
||||
|
||||
if (selected_widget_type - 1 < 0)
|
||||
new_index = N_WIDGET_TYPES - 1;
|
||||
else
|
||||
new_index = selected_widget_type - 1;
|
||||
gtk_fishbowl_set_count (GTK_FISHBOWL (bowl),
|
||||
gtk_fishbowl_get_count (GTK_FISHBOWL (bowl)) + suggested_change);
|
||||
stats_update (bowl);
|
||||
|
||||
set_widget_type (fishbowl, new_index);
|
||||
}
|
||||
|
||||
void
|
||||
changes_toggled_cb (GtkToggleButton *button,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (gtk_toggle_button_get_active (button))
|
||||
gtk_button_set_icon_name (GTK_BUTTON (button), "changes-prevent");
|
||||
else
|
||||
gtk_button_set_icon_name (GTK_BUTTON (button), "changes-allow");
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_fishbowl (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkCssProvider *provider = NULL;
|
||||
|
||||
if (provider == NULL)
|
||||
{
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider, css, -1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *bowl;
|
||||
GtkWidget *bowl, *info_label;
|
||||
|
||||
g_type_ensure (GTK_TYPE_FISHBOWL);
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fishbowl/fishbowl.ui");
|
||||
gtk_builder_add_callback_symbols (builder,
|
||||
"next_button_clicked_cb", G_CALLBACK (next_button_clicked_cb),
|
||||
"prev_button_clicked_cb", G_CALLBACK (prev_button_clicked_cb),
|
||||
"changes_toggled_cb", G_CALLBACK (changes_toggled_cb),
|
||||
NULL);
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
bowl = GTK_WIDGET (gtk_builder_get_object (builder, "bowl"));
|
||||
selected_widget_type = -1;
|
||||
set_widget_type (GTK_FISHBOWL (bowl), 0);
|
||||
gtk_fishbowl_set_use_icons (GTK_FISHBOWL (bowl), TRUE);
|
||||
info_label = GTK_WIDGET (gtk_builder_get_object (builder, "info_label"));
|
||||
allow_changes = GTK_WIDGET (gtk_builder_get_object (builder, "changes_allow"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_widget_realize (window);
|
||||
gtk_widget_add_tick_callback (bowl, move_fish, info_label, NULL);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
@@ -313,5 +174,6 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
|
||||
return window;
|
||||
}
|
||||
|
@@ -1,57 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<!-- interface-requires gtk+ 3.6 -->
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="title" translatable="yes">Fishbowl</property>
|
||||
<property name="default-width">400</property>
|
||||
<property name="default-height">400</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="">
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-start-symbolic</property>
|
||||
<signal name="clicked" handler="prev_button_clicked_cb" object="bowl" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-end-symbolic</property>
|
||||
<signal name="clicked" handler="next_button_clicked_cb" object="bowl" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<object class="GtkLabel" id="info_label">
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">fps</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" bind-source="bowl" bind-property="framerate-string"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Icons, </property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label" bind-source="bowl" bind-property="count"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="end">
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="changes_allow">
|
||||
<property name="visible" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean"/>
|
||||
<property name="icon-name">changes-allow</property>
|
||||
<property name="relief">none</property>
|
||||
<signal name="notify::active" handler="changes_toggled_cb"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkToggleButton" id="changes_prevent">
|
||||
<property name="active" bind-source="changes_allow" bind-property="active" bind-flags="bidirectional|invert-boolean">True</property>
|
||||
<property name="visible" bind-source="changes_prevent" bind-property="active" bind-flags="invert-boolean">False</property>
|
||||
<property name="icon-name">changes-prevent</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack-type">end</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -59,7 +48,6 @@
|
||||
<object class="GtkFishbowl" id="bowl">
|
||||
<property name="visible">True</property>
|
||||
<property name="animating">True</property>
|
||||
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean | sync-create"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@@ -1,167 +0,0 @@
|
||||
/* Fixed layout
|
||||
*
|
||||
* GtkFixed is a container that allows placing and transforming
|
||||
* widgets manually.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* This enumeration determines the paint order */
|
||||
enum {
|
||||
FACE_BACK,
|
||||
FACE_LEFT,
|
||||
FACE_BOTTOM,
|
||||
FACE_RIGHT,
|
||||
FACE_TOP,
|
||||
FACE_FRONT,
|
||||
|
||||
N_FACES
|
||||
};
|
||||
|
||||
/* Map face widgets to CSS classes */
|
||||
static struct {
|
||||
GtkWidget *face;
|
||||
const char *css_class;
|
||||
} faces[N_FACES] = {
|
||||
[FACE_BACK] = { NULL, "back", },
|
||||
[FACE_LEFT] = { NULL, "left", },
|
||||
[FACE_RIGHT] = { NULL, "right", },
|
||||
[FACE_TOP] = { NULL, "top", },
|
||||
[FACE_BOTTOM] = { NULL, "bottom", },
|
||||
[FACE_FRONT] = { NULL, "front", },
|
||||
};
|
||||
|
||||
static GtkWidget *
|
||||
create_faces (void)
|
||||
{
|
||||
GtkWidget *fixed = gtk_fixed_new ();
|
||||
int face_size = 200;
|
||||
float w, h, d, p;
|
||||
|
||||
gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE);
|
||||
|
||||
w = (float) face_size / 2.f;
|
||||
h = (float) face_size / 2.f;
|
||||
d = (float) face_size / 2.f;
|
||||
p = face_size * 3.f;
|
||||
|
||||
for (int i = 0; i < N_FACES; i++)
|
||||
{
|
||||
GskTransform *transform = NULL;
|
||||
|
||||
/* Add a face */
|
||||
faces[i].face = gtk_frame_new (NULL);
|
||||
gtk_widget_set_size_request (faces[i].face, face_size, face_size);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (faces[i].face), faces[i].css_class);
|
||||
gtk_container_add (GTK_CONTAINER (fixed), faces[i].face);
|
||||
|
||||
/* Set up the transformation for each face */
|
||||
transform = gsk_transform_translate (transform, &GRAPHENE_POINT_INIT (w, h));
|
||||
transform = gsk_transform_perspective (transform, p);
|
||||
transform = gsk_transform_rotate_3d (transform, -30.f, graphene_vec3_x_axis ());
|
||||
transform = gsk_transform_rotate_3d (transform, 135.f, graphene_vec3_y_axis ());
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0, 0, -face_size / 6.f));
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case FACE_FRONT:
|
||||
transform = gsk_transform_rotate_3d (transform, 0.f, graphene_vec3_y_axis ());
|
||||
break;
|
||||
|
||||
case FACE_BACK:
|
||||
transform = gsk_transform_rotate_3d (transform, -180.f, graphene_vec3_y_axis ());
|
||||
break;
|
||||
|
||||
case FACE_RIGHT:
|
||||
transform = gsk_transform_rotate_3d (transform, 90.f, graphene_vec3_y_axis ());
|
||||
break;
|
||||
|
||||
case FACE_LEFT:
|
||||
transform = gsk_transform_rotate_3d (transform, -90.f, graphene_vec3_y_axis ());
|
||||
break;
|
||||
|
||||
case FACE_TOP:
|
||||
transform = gsk_transform_rotate_3d (transform, 90.f, graphene_vec3_x_axis ());
|
||||
break;
|
||||
|
||||
case FACE_BOTTOM:
|
||||
transform = gsk_transform_rotate_3d (transform, -90.f, graphene_vec3_x_axis ());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (0, 0, d));
|
||||
transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (-w, -h, 0));
|
||||
|
||||
gtk_fixed_set_child_transform (GTK_FIXED (fixed), faces[i].face, transform);
|
||||
gsk_transform_unref (transform);
|
||||
}
|
||||
|
||||
return fixed;
|
||||
}
|
||||
|
||||
static GtkWidget *demo_window = NULL;
|
||||
static GtkCssProvider *provider = NULL;
|
||||
|
||||
static void
|
||||
close_window (GtkWidget *widget)
|
||||
{
|
||||
/* Reset the state */
|
||||
for (int i = 0; i < N_FACES; i++)
|
||||
faces[i].face = NULL;
|
||||
|
||||
gtk_style_context_remove_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider));
|
||||
provider = NULL;
|
||||
|
||||
demo_window = NULL;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_demo_window (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *window, *sw, *fixed, *cube;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Fixed layout");
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (close_window), NULL);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (window), sw);
|
||||
|
||||
fixed = gtk_fixed_new ();
|
||||
gtk_container_add (GTK_CONTAINER (sw), fixed);
|
||||
gtk_widget_set_halign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (GTK_WIDGET (fixed), GTK_ALIGN_CENTER);
|
||||
|
||||
cube = create_faces ();
|
||||
gtk_container_add (GTK_CONTAINER (fixed), cube);
|
||||
gtk_widget_set_overflow (fixed, GTK_OVERFLOW_VISIBLE);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/fixed/fixed.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
800);
|
||||
g_object_unref (provider);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
GtkWidget*
|
||||
do_fixed (GtkWidget *do_widget)
|
||||
{
|
||||
if (demo_window == NULL)
|
||||
demo_window = create_demo_window (do_widget);
|
||||
|
||||
if (!gtk_widget_get_visible (demo_window))
|
||||
gtk_widget_show (demo_window);
|
||||
else
|
||||
gtk_widget_destroy (demo_window);
|
||||
|
||||
return demo_window;
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
frame.front {
|
||||
border: 2px solid white;
|
||||
background-color: rgba(228, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
frame.back {
|
||||
border: 2px solid white;
|
||||
background-color: rgba(228, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
frame.right {
|
||||
border: 2px solid white;
|
||||
background-color: rgba(127, 231, 25, 0.8);
|
||||
}
|
||||
|
||||
frame.left {
|
||||
border: 2px solid white;
|
||||
background-color: rgba(127, 231, 25, 0.8);
|
||||
}
|
||||
|
||||
frame.top {
|
||||
border: 2px solid white;
|
||||
background-color: rgba(114, 159, 207, 0.8);
|
||||
}
|
||||
|
||||
frame.bottom {
|
||||
border: 2px solid white;
|
||||
background-color: rgba(114, 159, 207, 0.8);
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.18.1 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<object class="GtkWindow" id="window">
|
||||
@@ -41,7 +42,6 @@
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="font">Sans 12</property>
|
||||
<property name="level">family|style|size|variations|features</property>
|
||||
<signal name="font-set" handler="font_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
@@ -52,7 +52,7 @@
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Font Features</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
@@ -83,7 +83,7 @@
|
||||
<property name="label" translatable="yes">Font Variations</property>
|
||||
<property name="xalign">0</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
<attribute name="weight" value="bold"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
@@ -114,35 +114,32 @@
|
||||
<child>
|
||||
<object class="GtkStack" id="stack">
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">label</property>
|
||||
<property name="child">
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="wrap">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="selectable">1</property>
|
||||
</object>
|
||||
</property>
|
||||
<object class="GtkLabel" id="label">
|
||||
<property name="wrap">1</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="valign">start</property>
|
||||
<property name="selectable">1</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">label</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">entry</property>
|
||||
<property name="child">
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="text">Grumpy wizards make toxic brew for the evil Queen and Jack. A quick movement of the enemy will jeopardize six gunboats. The job of waxing linoleum frequently peeves chintzy kids. My girl wove six dozen plaid jackets before she quit. Twelve ziggurats quickly jumped a finch box.
|
||||
|
||||
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
|
||||
|
||||
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
|
||||
<signal name="activate" handler="stop_edit"/>
|
||||
<property name="valign">start</property>
|
||||
<property name="width-chars">50</property>
|
||||
</object>
|
||||
</property>
|
||||
<signal name="key-press-event" handler="entry_key_press"/>
|
||||
<signal name="activate" handler="stop_edit"/>
|
||||
<property name="valign">start</property>
|
||||
<property name="width-chars">50</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">entry</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
@@ -305,7 +305,7 @@ update_display (void)
|
||||
char *font_desc;
|
||||
char *features;
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
text = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||
|
||||
if (gtk_label_get_selection_bounds (GTK_LABEL (label), &ins, &bound))
|
||||
{
|
||||
@@ -495,11 +495,7 @@ update_script_combo (void)
|
||||
gboolean have_active = FALSE;
|
||||
|
||||
lang = gtk_font_chooser_get_language (GTK_FONT_CHOOSER (font));
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
active = hb_ot_tag_from_language (hb_language_from_string (lang, -1));
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
g_free (lang);
|
||||
|
||||
store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
|
||||
@@ -732,7 +728,7 @@ adjustment_changed (GtkAdjustment *adjustment,
|
||||
char *str;
|
||||
|
||||
str = g_strdup_printf ("%g", gtk_adjustment_get_value (adjustment));
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), str);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), str);
|
||||
g_free (str);
|
||||
|
||||
update_display ();
|
||||
@@ -745,7 +741,7 @@ entry_activated (GtkEntry *entry,
|
||||
gdouble value;
|
||||
gchar *err = NULL;
|
||||
|
||||
value = g_strtod (gtk_editable_get_text (GTK_EDITABLE (entry)), &err);
|
||||
value = g_strtod (gtk_entry_get_text (entry), &err);
|
||||
if (err != NULL)
|
||||
gtk_adjustment_set_value (adjustment, value);
|
||||
}
|
||||
@@ -825,7 +821,7 @@ add_axis (FT_Var_Axis *ax, FT_Fixed value, int i)
|
||||
gtk_grid_attach (GTK_GRID (variations_grid), axis_scale, 1, i, 1, 1);
|
||||
axis_entry = gtk_entry_new ();
|
||||
gtk_widget_set_valign (axis_entry, GTK_ALIGN_BASELINE);
|
||||
gtk_editable_set_width_chars (GTK_EDITABLE (axis_entry), 4);
|
||||
gtk_entry_set_width_chars (GTK_ENTRY (axis_entry), 4);
|
||||
gtk_grid_attach (GTK_GRID (variations_grid), axis_entry, 2, i, 1, 1);
|
||||
|
||||
axis = g_new (Axis, 1);
|
||||
@@ -1643,7 +1639,7 @@ static char *text;
|
||||
static void
|
||||
switch_to_entry (void)
|
||||
{
|
||||
text = g_strdup (gtk_editable_get_text (GTK_EDITABLE (entry)));
|
||||
text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), "entry");
|
||||
gtk_widget_grab_focus (entry);
|
||||
}
|
||||
@@ -1669,19 +1665,19 @@ toggle_edit (void)
|
||||
static void
|
||||
stop_edit (void)
|
||||
{
|
||||
g_signal_emit_by_name (edit_toggle, "clicked");
|
||||
gtk_button_clicked (GTK_BUTTON (edit_toggle));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_key_press (GtkEventController *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType modifiers,
|
||||
GtkEntry *entry)
|
||||
entry_key_press (GtkEntry *entry, GdkEventKey *event)
|
||||
{
|
||||
guint keyval;
|
||||
|
||||
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
|
||||
|
||||
if (keyval == GDK_KEY_Escape)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (entry), text);
|
||||
gtk_entry_set_text (GTK_ENTRY (entry), text);
|
||||
stop_edit ();
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
@@ -1698,7 +1694,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *feature_list;
|
||||
GtkEventController *controller;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/font_features/font-features.ui");
|
||||
|
||||
@@ -1708,6 +1703,7 @@ do_font_features (GtkWidget *do_widget)
|
||||
gtk_builder_add_callback_symbol (builder, "reset", reset_features);
|
||||
gtk_builder_add_callback_symbol (builder, "stop_edit", G_CALLBACK (stop_edit));
|
||||
gtk_builder_add_callback_symbol (builder, "toggle_edit", G_CALLBACK (toggle_edit));
|
||||
gtk_builder_add_callback_symbol (builder, "entry_key_press", G_CALLBACK (entry_key_press));
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
@@ -1722,11 +1718,6 @@ do_font_features (GtkWidget *do_widget)
|
||||
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
|
||||
edit_toggle = GTK_WIDGET (gtk_builder_get_object (builder, "edit_toggle"));
|
||||
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_object_set_data_full (G_OBJECT (entry), "controller", controller, g_object_unref);
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (entry_key_press), entry);
|
||||
gtk_widget_add_controller (entry, controller);
|
||||
|
||||
add_check_group (feature_list, _("Kerning"), (const char *[]){ "kern", NULL });
|
||||
add_check_group (feature_list, _("Ligatures"), (const char *[]){ "liga",
|
||||
"dlig",
|
||||
|
@@ -68,7 +68,8 @@ plane_snapshot (GtkWidget *widget,
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
cr = gtk_snapshot_append_cairo (snapshot,
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
&GRAPHENE_RECT_INIT (0, 0, width, height),
|
||||
"FontPlane");
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, width, height);
|
||||
@@ -207,26 +208,23 @@ plane_drag_gesture_end (GtkGestureDrag *gesture,
|
||||
static void
|
||||
gtk_font_plane_init (GtkFontPlane *plane)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (plane), FALSE);
|
||||
gtk_widget_set_can_focus (GTK_WIDGET (plane), TRUE);
|
||||
|
||||
gesture = gtk_gesture_drag_new ();
|
||||
g_signal_connect (gesture, "drag-begin",
|
||||
plane->drag_gesture = gtk_gesture_drag_new (GTK_WIDGET (plane));
|
||||
g_signal_connect (plane->drag_gesture, "drag-begin",
|
||||
G_CALLBACK (plane_drag_gesture_begin), plane);
|
||||
g_signal_connect (gesture, "drag-update",
|
||||
g_signal_connect (plane->drag_gesture, "drag-update",
|
||||
G_CALLBACK (plane_drag_gesture_update), plane);
|
||||
g_signal_connect (gesture, "drag-end",
|
||||
g_signal_connect (plane->drag_gesture, "drag-end",
|
||||
G_CALLBACK (plane_drag_gesture_end), plane);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0);
|
||||
gtk_widget_add_controller (GTK_WIDGET (plane), GTK_EVENT_CONTROLLER (gesture));
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (plane->drag_gesture), 0);
|
||||
|
||||
gesture = gtk_gesture_long_press_new ();
|
||||
g_signal_connect (gesture, "pressed",
|
||||
plane->long_press_gesture = gtk_gesture_long_press_new (GTK_WIDGET (plane));
|
||||
g_signal_connect (plane->long_press_gesture, "pressed",
|
||||
G_CALLBACK (hold_action), plane);
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture),
|
||||
gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (plane->long_press_gesture),
|
||||
TRUE);
|
||||
gtk_widget_add_controller (GTK_WIDGET (plane), GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -237,6 +235,9 @@ plane_finalize (GObject *object)
|
||||
g_clear_object (&plane->weight_adj);
|
||||
g_clear_object (&plane->width_adj);
|
||||
|
||||
g_clear_object (&plane->drag_gesture);
|
||||
g_clear_object (&plane->long_press_gesture);
|
||||
|
||||
G_OBJECT_CLASS (gtk_font_plane_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@@ -41,6 +41,7 @@ struct _GtkFontPlane
|
||||
GtkAdjustment *width_adj;
|
||||
|
||||
GtkGesture *drag_gesture;
|
||||
GtkGesture *long_press_gesture;
|
||||
};
|
||||
|
||||
struct _GtkFontPlaneClass
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/* Foreign drawing
|
||||
*
|
||||
* Many applications can't use GTK widgets, for a variety of reasons,
|
||||
* Many applications can't use GTK+ widgets, for a variety of reasons,
|
||||
* but still want their user interface to appear integrated with the
|
||||
* rest of the desktop, and follow GTK themes. This demo shows how to
|
||||
* rest of the desktop, and follow GTK+ themes. This demo shows how to
|
||||
* use GtkStyleContext and the gtk_render_ APIs to achieve this.
|
||||
*
|
||||
* Note that this is a very simple, non-interactive example.
|
||||
|
@@ -157,15 +157,16 @@ do_gestures (GtkWidget *do_widget)
|
||||
NULL, NULL);
|
||||
|
||||
/* Swipe */
|
||||
gesture = gtk_gesture_swipe_new ();
|
||||
gesture = gtk_gesture_swipe_new (drawing_area);
|
||||
g_signal_connect (gesture, "swipe",
|
||||
G_CALLBACK (swipe_gesture_swept), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* 3fg swipe for touchpads */
|
||||
gesture = g_object_new (GTK_TYPE_GESTURE_SWIPE,
|
||||
"widget", drawing_area,
|
||||
"n-points", 3,
|
||||
NULL);
|
||||
g_signal_connect (gesture, "begin",
|
||||
@@ -174,34 +175,33 @@ do_gestures (GtkWidget *do_widget)
|
||||
G_CALLBACK (swipe_gesture_swept), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* Long press */
|
||||
gesture = gtk_gesture_long_press_new ();
|
||||
gesture = gtk_gesture_long_press_new (drawing_area);
|
||||
g_signal_connect (gesture, "pressed",
|
||||
G_CALLBACK (long_press_gesture_pressed), drawing_area);
|
||||
g_signal_connect (gesture, "end",
|
||||
G_CALLBACK (long_press_gesture_end), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* Rotate */
|
||||
rotate = gesture = gtk_gesture_rotate_new ();
|
||||
rotate = gesture = gtk_gesture_rotate_new (drawing_area);
|
||||
g_signal_connect (gesture, "angle-changed",
|
||||
G_CALLBACK (rotation_angle_changed), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
|
||||
/* Zoom */
|
||||
zoom = gesture = gtk_gesture_zoom_new ();
|
||||
zoom = gesture = gtk_gesture_zoom_new (drawing_area);
|
||||
g_signal_connect (gesture, "scale-changed",
|
||||
G_CALLBACK (zoom_scale_changed), drawing_area);
|
||||
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
|
||||
GTK_PHASE_BUBBLE);
|
||||
gtk_widget_add_controller (drawing_area, GTK_EVENT_CONTROLLER (gesture));
|
||||
g_object_weak_ref (G_OBJECT (drawing_area), (GWeakNotify) g_object_unref, gesture);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -1,8 +1,8 @@
|
||||
[Desktop Entry]
|
||||
Name=GTK Demo
|
||||
Comment=GTK code examples and demonstrations
|
||||
Name=GTK+ Demo
|
||||
Comment=GTK+ code examples and demonstrations
|
||||
Exec=gtk4-demo
|
||||
Icon=org.gtk.Demo4
|
||||
Icon=gtk4-demo
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
@@ -24,18 +24,13 @@ typedef struct _GtkFishbowlChild GtkFishbowlChild;
|
||||
|
||||
struct _GtkFishbowlPrivate
|
||||
{
|
||||
GtkFishCreationFunc creation_func;
|
||||
GList *children;
|
||||
guint count;
|
||||
|
||||
gint64 last_frame_time;
|
||||
gint64 update_delay;
|
||||
guint tick_id;
|
||||
|
||||
double framerate;
|
||||
int last_benchmark_change;
|
||||
|
||||
guint benchmark : 1;
|
||||
guint use_icons: 1;
|
||||
};
|
||||
|
||||
struct _GtkFishbowlChild
|
||||
@@ -50,24 +45,18 @@ struct _GtkFishbowlChild
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ANIMATING,
|
||||
PROP_BENCHMARK,
|
||||
PROP_COUNT,
|
||||
PROP_FRAMERATE,
|
||||
PROP_FRAMERATE_STRING,
|
||||
PROP_UPDATE_DELAY,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkFishbowl, gtk_fishbowl, GTK_TYPE_WIDGET)
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkFishbowl, gtk_fishbowl, GTK_TYPE_CONTAINER)
|
||||
|
||||
static void
|
||||
gtk_fishbowl_init (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
priv->update_delay = G_USEC_PER_SEC;
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (fishbowl), FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,6 +72,15 @@ gtk_fishbowl_new (void)
|
||||
return g_object_new (GTK_TYPE_FISHBOWL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
|
||||
gboolean use_icons)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
priv->use_icons = use_icons;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
@@ -127,10 +125,10 @@ gtk_fishbowl_measure (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
const GtkAllocation *allocation,
|
||||
int baseline,
|
||||
GtkAllocation *out_clip)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (widget);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
@@ -141,18 +139,20 @@ gtk_fishbowl_size_allocate (GtkWidget *widget,
|
||||
|
||||
for (children = priv->children; children; children = children->next)
|
||||
{
|
||||
GtkAllocation child_clip;
|
||||
|
||||
child = children->data;
|
||||
|
||||
if (!gtk_widget_get_visible (child->widget))
|
||||
continue;
|
||||
|
||||
gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
|
||||
child_allocation.x = round (child->x * (width - child_requisition.width));
|
||||
child_allocation.y = round (child->y * (height - child_requisition.height));
|
||||
child_allocation.x = allocation->x + round (child->x * (allocation->width - child_requisition.width));
|
||||
child_allocation.y = allocation->y + round (child->y * (allocation->height - child_requisition.height));
|
||||
child_allocation.width = child_requisition.width;
|
||||
child_allocation.height = child_requisition.height;
|
||||
|
||||
gtk_widget_size_allocate (child->widget, &child_allocation, -1);
|
||||
gtk_widget_size_allocate (child->widget, &child_allocation, -1, &child_clip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,9 +164,10 @@ new_speed (void)
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_add (GtkFishbowl *fishbowl,
|
||||
GtkWidget *widget)
|
||||
gtk_fishbowl_add (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child_info;
|
||||
|
||||
@@ -188,12 +189,13 @@ gtk_fishbowl_add (GtkFishbowl *fishbowl,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
GtkWidget *widget)
|
||||
gtk_fishbowl_remove (GtkContainer *container,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child;
|
||||
GtkWidget *widget_bowl = GTK_WIDGET (fishbowl);
|
||||
GtkWidget *widget_container = GTK_WIDGET (container);
|
||||
GList *children;
|
||||
|
||||
for (children = priv->children; children; children = children->next)
|
||||
@@ -210,8 +212,8 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
g_list_free (children);
|
||||
g_free (child);
|
||||
|
||||
if (was_visible && gtk_widget_get_visible (widget_bowl))
|
||||
gtk_widget_queue_resize (widget_bowl);
|
||||
if (was_visible && gtk_widget_get_visible (widget_container))
|
||||
gtk_widget_queue_resize (widget_container);
|
||||
|
||||
priv->count--;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_COUNT]);
|
||||
@@ -220,6 +222,26 @@ gtk_fishbowl_remove (GtkFishbowl *fishbowl,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_forall (GtkContainer *container,
|
||||
GtkCallback callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
GtkFishbowl *fishbowl = GTK_FISHBOWL (container);
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GtkFishbowlChild *child;
|
||||
GList *children;
|
||||
|
||||
children = priv->children;
|
||||
while (children)
|
||||
{
|
||||
child = children->data;
|
||||
children = children->next;
|
||||
|
||||
(* callback) (child->widget, callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_dispose (GObject *object)
|
||||
{
|
||||
@@ -245,18 +267,10 @@ gtk_fishbowl_set_property (GObject *object,
|
||||
gtk_fishbowl_set_animating (fishbowl, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_BENCHMARK:
|
||||
gtk_fishbowl_set_benchmark (fishbowl, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_COUNT:
|
||||
gtk_fishbowl_set_count (fishbowl, g_value_get_uint (value));
|
||||
break;
|
||||
|
||||
case PROP_UPDATE_DELAY:
|
||||
gtk_fishbowl_set_update_delay (fishbowl, g_value_get_int64 (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -277,30 +291,10 @@ gtk_fishbowl_get_property (GObject *object,
|
||||
g_value_set_boolean (value, gtk_fishbowl_get_animating (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_BENCHMARK:
|
||||
g_value_set_boolean (value, gtk_fishbowl_get_benchmark (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_COUNT:
|
||||
g_value_set_uint (value, gtk_fishbowl_get_count (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_FRAMERATE:
|
||||
g_value_set_double (value, gtk_fishbowl_get_framerate (fishbowl));
|
||||
break;
|
||||
|
||||
case PROP_FRAMERATE_STRING:
|
||||
{
|
||||
char *s = g_strdup_printf ("%.2f", gtk_fishbowl_get_framerate (fishbowl));
|
||||
g_value_set_string (value, s);
|
||||
g_free (s);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_UPDATE_DELAY:
|
||||
g_value_set_int64 (value, gtk_fishbowl_get_update_delay (fishbowl));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -312,6 +306,7 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_fishbowl_dispose;
|
||||
object_class->set_property = gtk_fishbowl_set_property;
|
||||
@@ -320,6 +315,10 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
widget_class->measure = gtk_fishbowl_measure;
|
||||
widget_class->size_allocate = gtk_fishbowl_size_allocate;
|
||||
|
||||
container_class->add = gtk_fishbowl_add;
|
||||
container_class->remove = gtk_fishbowl_remove;
|
||||
container_class->forall = gtk_fishbowl_forall;
|
||||
|
||||
props[PROP_ANIMATING] =
|
||||
g_param_spec_boolean ("animating",
|
||||
"animating",
|
||||
@@ -327,43 +326,13 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
props[PROP_BENCHMARK] =
|
||||
g_param_spec_boolean ("benchmark",
|
||||
"Benchmark",
|
||||
"Adapt the count property to hit the maximum framerate",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
props[PROP_COUNT] =
|
||||
g_param_spec_uint ("count",
|
||||
"Count",
|
||||
"Number of widgets",
|
||||
0, G_MAXUINT,
|
||||
0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
props[PROP_FRAMERATE] =
|
||||
g_param_spec_double ("framerate",
|
||||
"Framerate",
|
||||
"Framerate of this widget in frames per second",
|
||||
0, G_MAXDOUBLE,
|
||||
0,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
props[PROP_FRAMERATE_STRING] =
|
||||
g_param_spec_string ("framerate-string",
|
||||
"Framerate as string",
|
||||
"Framerate as string, with 2 decimals",
|
||||
NULL,
|
||||
G_PARAM_READABLE);
|
||||
|
||||
props[PROP_UPDATE_DELAY] =
|
||||
g_param_spec_int64 ("update-delay",
|
||||
"Update delay",
|
||||
"Number of usecs between updates",
|
||||
0, G_MAXINT64,
|
||||
G_USEC_PER_SEC,
|
||||
G_PARAM_READWRITE);
|
||||
G_PARAM_READABLE);
|
||||
|
||||
g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
|
||||
}
|
||||
@@ -376,58 +345,96 @@ gtk_fishbowl_get_count (GtkFishbowl *fishbowl)
|
||||
return priv->count;
|
||||
}
|
||||
|
||||
char **icon_names = NULL;
|
||||
gsize n_icon_names = 0;
|
||||
|
||||
static void
|
||||
init_icon_names (GtkIconTheme *theme)
|
||||
{
|
||||
GPtrArray *icons;
|
||||
GList *l, *icon_list;
|
||||
|
||||
if (icon_names)
|
||||
return;
|
||||
|
||||
icon_list = gtk_icon_theme_list_icons (theme, NULL);
|
||||
icons = g_ptr_array_new ();
|
||||
|
||||
for (l = icon_list; l; l = l->next)
|
||||
{
|
||||
if (g_str_has_suffix (l->data, "symbolic"))
|
||||
continue;
|
||||
|
||||
g_ptr_array_add (icons, g_strdup (l->data));
|
||||
}
|
||||
|
||||
n_icon_names = icons->len;
|
||||
g_ptr_array_add (icons, NULL); /* NULL-terminate the array */
|
||||
icon_names = (char **) g_ptr_array_free (icons, FALSE);
|
||||
|
||||
/* don't free strings, we assigned them to the array */
|
||||
g_list_free_full (icon_list, g_free);
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_random_icon_name (GtkIconTheme *theme)
|
||||
{
|
||||
init_icon_names (theme);
|
||||
|
||||
return icon_names[g_random_int_range(0, n_icon_names)];
|
||||
}
|
||||
|
||||
static GType
|
||||
get_random_widget_type ()
|
||||
{
|
||||
GType types[] = {
|
||||
GTK_TYPE_SWITCH,
|
||||
GTK_TYPE_BUTTON,
|
||||
GTK_TYPE_ENTRY,
|
||||
GTK_TYPE_SPIN_BUTTON,
|
||||
GTK_TYPE_FONT_BUTTON,
|
||||
GTK_TYPE_SCROLLBAR,
|
||||
GTK_TYPE_SCALE,
|
||||
GTK_TYPE_LEVEL_BAR,
|
||||
GTK_TYPE_PROGRESS_BAR,
|
||||
GTK_TYPE_RADIO_BUTTON,
|
||||
GTK_TYPE_CHECK_BUTTON
|
||||
};
|
||||
return types[g_random_int_range (0, G_N_ELEMENTS (types))];
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
||||
guint count)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
if (priv->count == count)
|
||||
return;
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (fishbowl));
|
||||
|
||||
while (priv->count > count)
|
||||
{
|
||||
gtk_fishbowl_remove (fishbowl, gtk_widget_get_first_child (GTK_WIDGET (fishbowl)));
|
||||
gtk_container_remove (GTK_CONTAINER (fishbowl),
|
||||
((GtkFishbowlChild *) priv->children->data)->widget);
|
||||
}
|
||||
|
||||
while (priv->count < count)
|
||||
{
|
||||
GtkWidget *new_widget;
|
||||
|
||||
new_widget = priv->creation_func ();
|
||||
if (priv->use_icons)
|
||||
{
|
||||
new_widget = gtk_image_new_from_icon_name (get_random_icon_name (gtk_icon_theme_get_default ()));
|
||||
gtk_image_set_icon_size (GTK_IMAGE (new_widget), GTK_ICON_SIZE_LARGE);
|
||||
}
|
||||
else
|
||||
new_widget = g_object_new (get_random_widget_type (), NULL);
|
||||
|
||||
gtk_fishbowl_add (fishbowl, new_widget);
|
||||
gtk_container_add (GTK_CONTAINER (fishbowl), new_widget);
|
||||
}
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (fishbowl));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
return priv->benchmark;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
|
||||
gboolean benchmark)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
if (priv->benchmark == benchmark)
|
||||
return;
|
||||
|
||||
priv->benchmark = benchmark;
|
||||
if (!benchmark)
|
||||
priv->last_benchmark_change = 0;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_BENCHMARK]);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
|
||||
{
|
||||
@@ -436,114 +443,6 @@ gtk_fishbowl_get_animating (GtkFishbowl *fishbowl)
|
||||
return priv->tick_id != 0;
|
||||
}
|
||||
|
||||
static gint64
|
||||
guess_refresh_interval (GdkFrameClock *frame_clock)
|
||||
{
|
||||
gint64 interval;
|
||||
gint64 i;
|
||||
|
||||
interval = G_MAXINT64;
|
||||
|
||||
for (i = gdk_frame_clock_get_history_start (frame_clock);
|
||||
i < gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
i++)
|
||||
{
|
||||
GdkFrameTimings *t, *before;
|
||||
gint64 ts, before_ts;
|
||||
|
||||
t = gdk_frame_clock_get_timings (frame_clock, i);
|
||||
before = gdk_frame_clock_get_timings (frame_clock, i - 1);
|
||||
if (t == NULL || before == NULL)
|
||||
continue;
|
||||
|
||||
ts = gdk_frame_timings_get_frame_time (t);
|
||||
before_ts = gdk_frame_timings_get_frame_time (before);
|
||||
if (ts == 0 || before_ts == 0)
|
||||
continue;
|
||||
|
||||
interval = MIN (interval, ts - before_ts);
|
||||
}
|
||||
|
||||
if (interval == G_MAXINT64)
|
||||
return 0;
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
GdkFrameClock *frame_clock;
|
||||
GdkFrameTimings *start, *end;
|
||||
gint64 start_counter, end_counter;
|
||||
gint64 n_frames, expected_frames;
|
||||
gint64 start_timestamp, end_timestamp;
|
||||
gint64 interval;
|
||||
|
||||
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (fishbowl));
|
||||
if (frame_clock == NULL)
|
||||
return;
|
||||
|
||||
start_counter = gdk_frame_clock_get_history_start (frame_clock);
|
||||
end_counter = gdk_frame_clock_get_frame_counter (frame_clock);
|
||||
start = gdk_frame_clock_get_timings (frame_clock, start_counter);
|
||||
for (end = gdk_frame_clock_get_timings (frame_clock, end_counter);
|
||||
end_counter > start_counter && end != NULL && !gdk_frame_timings_get_complete (end);
|
||||
end = gdk_frame_clock_get_timings (frame_clock, end_counter))
|
||||
end_counter--;
|
||||
if (end_counter - start_counter < 4)
|
||||
return;
|
||||
|
||||
start_timestamp = gdk_frame_timings_get_presentation_time (start);
|
||||
end_timestamp = gdk_frame_timings_get_presentation_time (end);
|
||||
if (start_timestamp == 0 || end_timestamp == 0)
|
||||
{
|
||||
start_timestamp = gdk_frame_timings_get_frame_time (start);
|
||||
end_timestamp = gdk_frame_timings_get_frame_time (end);
|
||||
}
|
||||
|
||||
n_frames = end_counter - start_counter;
|
||||
priv->framerate = ((double) n_frames) * G_USEC_PER_SEC / (end_timestamp - start_timestamp);
|
||||
priv->framerate = ((int)(priv->framerate * 100))/100.0;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE_STRING]);
|
||||
|
||||
if (!priv->benchmark)
|
||||
return;
|
||||
|
||||
interval = gdk_frame_timings_get_refresh_interval (end);
|
||||
if (interval == 0)
|
||||
{
|
||||
interval = guess_refresh_interval (frame_clock);
|
||||
if (interval == 0)
|
||||
return;
|
||||
}
|
||||
expected_frames = round ((double) (end_timestamp - start_timestamp) / interval);
|
||||
|
||||
if (n_frames >= expected_frames)
|
||||
{
|
||||
if (priv->last_benchmark_change > 0)
|
||||
priv->last_benchmark_change *= 2;
|
||||
else
|
||||
priv->last_benchmark_change = 1;
|
||||
}
|
||||
else if (n_frames + 1 < expected_frames)
|
||||
{
|
||||
if (priv->last_benchmark_change < 0)
|
||||
priv->last_benchmark_change--;
|
||||
else
|
||||
priv->last_benchmark_change = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->last_benchmark_change = 0;
|
||||
}
|
||||
|
||||
gtk_fishbowl_set_count (fishbowl, MAX (1, (int) priv->count + priv->last_benchmark_change));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_fishbowl_tick (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
@@ -554,11 +453,9 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
||||
GtkFishbowlChild *child;
|
||||
GList *l;
|
||||
gint64 frame_time, elapsed;
|
||||
gboolean do_update;
|
||||
|
||||
frame_time = gdk_frame_clock_get_frame_time (gtk_widget_get_frame_clock (widget));
|
||||
elapsed = frame_time - priv->last_frame_time;
|
||||
do_update = frame_time / priv->update_delay != priv->last_frame_time / priv->update_delay;
|
||||
priv->last_frame_time = frame_time;
|
||||
|
||||
/* last frame was 0, so we're just starting to animate */
|
||||
@@ -597,9 +494,6 @@ gtk_fishbowl_tick (GtkWidget *widget,
|
||||
|
||||
gtk_widget_queue_allocate (widget);
|
||||
|
||||
if (do_update)
|
||||
gtk_fishbowl_do_update (fishbowl);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
@@ -624,57 +518,8 @@ gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
||||
priv->last_frame_time = 0;
|
||||
gtk_widget_remove_tick_callback (GTK_WIDGET (fishbowl), priv->tick_id);
|
||||
priv->tick_id = 0;
|
||||
priv->framerate = 0;
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_FRAMERATE]);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_ANIMATING]);
|
||||
}
|
||||
|
||||
double
|
||||
gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
return priv->framerate;
|
||||
}
|
||||
|
||||
gint64
|
||||
gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
return priv->update_delay;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
|
||||
gint64 update_delay)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
if (priv->update_delay == update_delay)
|
||||
return;
|
||||
|
||||
priv->update_delay = update_delay;
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (fishbowl), props[PROP_UPDATE_DELAY]);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_fishbowl_set_creation_func (GtkFishbowl *fishbowl,
|
||||
GtkFishCreationFunc creation_func)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (fishbowl));
|
||||
|
||||
gtk_fishbowl_set_count (fishbowl, 0);
|
||||
priv->last_benchmark_change = 0;
|
||||
|
||||
priv->creation_func = creation_func;
|
||||
|
||||
gtk_fishbowl_set_count (fishbowl, 1);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (fishbowl));
|
||||
}
|
||||
|
@@ -32,37 +32,29 @@ G_BEGIN_DECLS
|
||||
typedef struct _GtkFishbowl GtkFishbowl;
|
||||
typedef struct _GtkFishbowlClass GtkFishbowlClass;
|
||||
|
||||
typedef GtkWidget * (* GtkFishCreationFunc) (void);
|
||||
|
||||
struct _GtkFishbowl
|
||||
{
|
||||
GtkWidget parent;
|
||||
GtkContainer container;
|
||||
};
|
||||
|
||||
struct _GtkFishbowlClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
GtkContainerClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_fishbowl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget* gtk_fishbowl_new (void);
|
||||
|
||||
void gtk_fishbowl_set_use_icons (GtkFishbowl *fishbowl,
|
||||
gboolean use_icons);
|
||||
|
||||
guint gtk_fishbowl_get_count (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_count (GtkFishbowl *fishbowl,
|
||||
guint count);
|
||||
gboolean gtk_fishbowl_get_animating (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_animating (GtkFishbowl *fishbowl,
|
||||
gboolean animating);
|
||||
gboolean gtk_fishbowl_get_benchmark (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_benchmark (GtkFishbowl *fishbowl,
|
||||
gboolean animating);
|
||||
double gtk_fishbowl_get_framerate (GtkFishbowl *fishbowl);
|
||||
gint64 gtk_fishbowl_get_update_delay (GtkFishbowl *fishbowl);
|
||||
void gtk_fishbowl_set_update_delay (GtkFishbowl *fishbowl,
|
||||
gint64 update_delay);
|
||||
void gtk_fishbowl_set_creation_func (GtkFishbowl *fishbowl,
|
||||
GtkFishCreationFunc creation_func);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -105,14 +105,14 @@ follow_if_link (GtkWidget *text_view,
|
||||
/* Links can be activated by pressing Enter.
|
||||
*/
|
||||
static gboolean
|
||||
key_pressed (GtkEventController *controller,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType modifiers,
|
||||
GtkWidget *text_view)
|
||||
key_press_event (GtkWidget *text_view,
|
||||
GdkEventKey *event)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
GtkTextBuffer *buffer;
|
||||
guint keyval;
|
||||
|
||||
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
|
||||
|
||||
switch (keyval)
|
||||
{
|
||||
@@ -128,49 +128,62 @@ key_pressed (GtkEventController *controller,
|
||||
break;
|
||||
}
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void set_cursor_if_appropriate (GtkTextView *text_view,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
static void
|
||||
released_cb (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *text_view)
|
||||
/* Links can also be activated by clicking or tapping.
|
||||
*/
|
||||
static gboolean
|
||||
event_cb (GtkWidget *text_view,
|
||||
GdkEvent *ev)
|
||||
{
|
||||
GtkTextIter start, end, iter;
|
||||
GtkTextBuffer *buffer;
|
||||
int tx, ty;
|
||||
gdouble ex, ey;
|
||||
int x, y;
|
||||
GdkEventType type;
|
||||
|
||||
if (gtk_gesture_single_get_button (GTK_GESTURE_SINGLE (gesture)) > 1)
|
||||
return;
|
||||
type = gdk_event_get_event_type (ev);
|
||||
|
||||
gdk_event_get_coords (ev, &ex, &ey);
|
||||
gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view),
|
||||
GTK_TEXT_WINDOW_WIDGET,
|
||||
x, y, &tx, &ty);
|
||||
ex, ey, &x, &y);
|
||||
|
||||
if (type == GDK_BUTTON_RELEASE)
|
||||
{
|
||||
guint button;
|
||||
|
||||
gdk_event_get_button (ev, &button);
|
||||
if (button != GDK_BUTTON_PRIMARY)
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_MOTION_NOTIFY)
|
||||
{
|
||||
set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y);
|
||||
return FALSE;
|
||||
}
|
||||
else if (type == GDK_TOUCH_END)
|
||||
{
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
|
||||
/* we shouldn't follow a link if the user has selected something */
|
||||
gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
|
||||
if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
if (gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y))
|
||||
follow_if_link (text_view, &iter);
|
||||
}
|
||||
|
||||
static void
|
||||
motion_cb (GtkEventControllerMotion *controller,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkTextView *text_view)
|
||||
{
|
||||
set_cursor_if_appropriate (text_view, x, y);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean hovering_over_link = FALSE;
|
||||
@@ -228,7 +241,6 @@ do_hypertext (GtkWidget *do_widget)
|
||||
GtkWidget *view;
|
||||
GtkWidget *sw;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkEventController *controller;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Hypertext");
|
||||
@@ -243,19 +255,10 @@ do_hypertext (GtkWidget *do_widget)
|
||||
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
|
||||
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (view), 20);
|
||||
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (view), 20);
|
||||
controller = gtk_event_controller_key_new ();
|
||||
g_signal_connect (controller, "key-pressed", G_CALLBACK (key_pressed), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
|
||||
g_signal_connect (controller, "released",
|
||||
G_CALLBACK (released_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
controller = gtk_event_controller_motion_new ();
|
||||
g_signal_connect (controller, "motion",
|
||||
G_CALLBACK (motion_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
g_signal_connect (view, "key-press-event",
|
||||
G_CALLBACK (key_press_event), NULL);
|
||||
g_signal_connect (view, "event",
|
||||
G_CALLBACK (event_cb), NULL);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
|
Before Width: | Height: | Size: 659 B |
Before Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 330 B |
Before Width: | Height: | Size: 420 B |
Before Width: | Height: | Size: 459 B |
Before Width: | Height: | Size: 401 B |
Before Width: | Height: | Size: 781 B |
Before Width: | Height: | Size: 582 B |
Before Width: | Height: | Size: 582 B |
Before Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 185 B |
Before Width: | Height: | Size: 422 B |
Before Width: | Height: | Size: 208 B |
Before Width: | Height: | Size: 682 B |