Compare commits
1 Commits
css-style-
...
cube-spin
Author | SHA1 | Date | |
---|---|---|---|
|
47ffaefa25 |
@@ -1,7 +1,7 @@
|
||||
stages:
|
||||
- build
|
||||
- flatpak
|
||||
# - deploy
|
||||
- deploy
|
||||
|
||||
.cache-paths: &cache-paths
|
||||
paths:
|
||||
@@ -12,33 +12,20 @@ stages:
|
||||
- subprojects/libepoxy/
|
||||
- subprojects/pango/
|
||||
|
||||
fedora-x86_64: &fedora-x86_64-defaults
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v9
|
||||
fedora-x86_64:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
|
||||
stage: build
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/test-docker.sh
|
||||
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"
|
||||
- "${CI_PROJECT_DIR}/_build/testsuite/css/output/*.syscap"
|
||||
cache:
|
||||
key: "$CI_JOB_NAME"
|
||||
<<: *cache-paths
|
||||
|
||||
fedora-x86_64-staticlibs:
|
||||
variables:
|
||||
EXTRA_MESON_FLAGS: "-Ddefault_library=both"
|
||||
<<: *fedora-x86_64-defaults
|
||||
|
||||
.mingw-defaults: &mingw-defaults
|
||||
stage: build
|
||||
tags:
|
||||
@@ -66,60 +53,30 @@ msys2-mingw32:
|
||||
script:
|
||||
- bash -x ./.gitlab-ci/flatpak-build.sh "${APPID}"
|
||||
|
||||
# Manual jobs, for branches and MRs
|
||||
.flatpak-manual: &flatpak-manual
|
||||
flatpak:demo:
|
||||
variables:
|
||||
APPID: org.gtk.Demo
|
||||
<<: *flatpak-defaults
|
||||
when: manual
|
||||
|
||||
# Only build Flatpak bundles automatically on master
|
||||
.flatpak-master: &flatpak-master
|
||||
flatpak:widget-factory:
|
||||
variables:
|
||||
APPID: org.gtk.WidgetFactory
|
||||
<<: *flatpak-defaults
|
||||
|
||||
pages:
|
||||
image: registry.gitlab.gnome.org/gnome/gtk/master:v3
|
||||
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/
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
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 -Dgtk_doc=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/
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - public
|
||||
# only:
|
||||
# - master
|
||||
|
@@ -1,6 +1,7 @@
|
||||
FROM fedora:31
|
||||
FROM fedora:29
|
||||
|
||||
RUN dnf -y install \
|
||||
hicolor-icon-theme \
|
||||
adwaita-icon-theme \
|
||||
atk-devel \
|
||||
at-spi2-atk-devel \
|
||||
@@ -10,10 +11,7 @@ RUN dnf -y install \
|
||||
ccache \
|
||||
colord-devel \
|
||||
cups-devel \
|
||||
dbus-daemon \
|
||||
dejavu-sans-mono-fonts \
|
||||
desktop-file-utils \
|
||||
diffutils \
|
||||
elfutils-libelf-devel \
|
||||
fribidi-devel \
|
||||
gcc \
|
||||
@@ -32,7 +30,6 @@ RUN dnf -y install \
|
||||
gstreamer1-plugins-bad-free-devel \
|
||||
gstreamer1-plugins-base-devel \
|
||||
gtk-doc \
|
||||
hicolor-icon-theme \
|
||||
iso-codes \
|
||||
itstool \
|
||||
json-glib-devel \
|
||||
@@ -53,7 +50,6 @@ RUN dnf -y install \
|
||||
libxkbcommon-devel \
|
||||
libXrandr-devel \
|
||||
libXrender-devel \
|
||||
libXtst-devel \
|
||||
libxslt \
|
||||
mesa-dri-drivers \
|
||||
mesa-libEGL-devel \
|
||||
@@ -62,12 +58,10 @@ RUN dnf -y install \
|
||||
pango-devel \
|
||||
pcre-devel \
|
||||
python3 \
|
||||
python3-jinja2 \
|
||||
python3-pip \
|
||||
python3-wheel \
|
||||
redhat-rpm-config \
|
||||
sassc \
|
||||
sysprof-devel \
|
||||
systemtap-sdt-devel \
|
||||
vulkan-devel \
|
||||
wayland-devel \
|
||||
@@ -76,7 +70,7 @@ RUN dnf -y install \
|
||||
xorg-x11-server-Xvfb \
|
||||
&& dnf clean all
|
||||
|
||||
RUN pip3 install meson==0.50.1
|
||||
RUN pip3 install meson==0.50.0
|
||||
|
||||
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><a name="summary">Summary</a></h3>
|
||||
<ul>
|
||||
<li><strong>Total units:</strong> {{ report.total_units }}</li>
|
||||
<li><strong>Passed:</strong> <a href="#passed">{{ report.total_successes }}</a></li>
|
||||
<li><strong>Failed:</strong> <a href="#failures">{{ report.total_failures }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% for suite_result in report.results_list %}
|
||||
<section>
|
||||
<div class="result">
|
||||
<h3><a name="results">Suite: {{ suite_result.suite_name }}</a></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><a name="passed">Passed</a></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><a name="skipped">Skipped</a></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><a name="expected-fail">Expected failures</a></h4>
|
||||
<ul>
|
||||
{% for success in suite_result.successes if success.result == 'EXPECTEDFAIL' %}
|
||||
<li><a name="{{ success.name }}">{{ success.name }}</a> - 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><a name="failed">Failed</a></h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'FAIL' %}
|
||||
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - 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><a name="timed-out">Timed out</a></h4>
|
||||
<ul class="failed">
|
||||
{% for failure in suite_result.failures if failure.result == 'TIMEOUT' %}
|
||||
<li><a name="{{ failure.name }}">{{ failure.name }}</a> - 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:v7"
|
||||
TAG="registry.gitlab.gnome.org/gnome/gtk/master:v3"
|
||||
|
||||
sudo docker build --build-arg HOST_USER_ID="$UID" --tag "${TAG}" \
|
||||
--file "Dockerfile" .
|
||||
|
@@ -16,9 +16,6 @@ meson \
|
||||
-Dwayland-backend=true \
|
||||
-Dbroadway-backend=true \
|
||||
-Dvulkan=yes \
|
||||
-Dprofiler=true \
|
||||
--werror \
|
||||
${EXTRA_MESON_FLAGS:-} \
|
||||
_build $srcdir
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
@@ -27,30 +24,11 @@ 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:gsk \
|
||||
--no-suite=gtk:reftest \
|
||||
--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
|
||||
|
@@ -33,10 +33,6 @@ pacman --noconfirm -S --needed \
|
||||
mingw-w64-$MSYS2_ARCH-gst-plugins-bad \
|
||||
mingw-w64-$MSYS2_ARCH-shared-mime-info
|
||||
|
||||
# https://gitlab.gnome.org/GNOME/gtk/issues/2243
|
||||
wget "https://gitlab.gnome.org/creiter/gitlab-ci-win32-runner/raw/master/pango/mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
|
||||
pacman --noconfirm -U "mingw-w64-$MSYS2_ARCH-pango-1.44.7-1-any.pkg.tar.xz"
|
||||
|
||||
mkdir -p _ccache
|
||||
export CCACHE_BASEDIR="$(pwd)"
|
||||
export CCACHE_DIR="${CCACHE_BASEDIR}/_ccache"
|
||||
@@ -46,11 +42,10 @@ ccache --zero-stats
|
||||
ccache --show-stats
|
||||
export CCACHE_DISABLE=true
|
||||
meson \
|
||||
-Dx11-backend=false \
|
||||
-Dwayland-backend=false \
|
||||
-Dwin32-backend=true \
|
||||
-Denable-x11-backend=false \
|
||||
-Denable-wayland-backend=false \
|
||||
-Denable-win32-backend=true \
|
||||
-Dvulkan=no \
|
||||
--werror \
|
||||
_build
|
||||
unset CCACHE_DISABLE
|
||||
|
||||
|
@@ -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
|
||||
@@ -26,7 +26,7 @@
|
||||
- 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
|
||||
- If you built GTK+ yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Additional information
|
||||
|
@@ -16,7 +16,7 @@
|
||||
- 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
|
||||
- If you built GTK+ yourself, the list of options used to configure the build
|
||||
-->
|
||||
|
||||
## Warnings
|
||||
|
@@ -174,7 +174,7 @@ maintainers review your contribution.
|
||||
|
||||
Each contribution is reviewed by the core developers of the GTK project.
|
||||
|
||||
The [CODEOWNERS](./docs/CODEOWNERS) document contains the list of core
|
||||
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.
|
||||
|
||||
|
102
NEWS
102
NEWS
@@ -1,105 +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
|
||||
==================================
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"app-id": "org.gtk.Demo4",
|
||||
"app-id": "org.gtk.Demo",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
@@ -9,9 +9,10 @@
|
||||
"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",
|
@@ -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,5 +1,5 @@
|
||||
{
|
||||
"app-id": "org.gtk.WidgetFactory4",
|
||||
"app-id": "org.gtk.WidgetFactory",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "master",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
@@ -9,9 +9,10 @@
|
||||
"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",
|
@@ -19,7 +19,7 @@ if 'DESTDIR' not in os.environ:
|
||||
os.path.join(gtk_datadir, 'glib-2.0', 'schemas')])
|
||||
|
||||
print('Updating icon cache...')
|
||||
subprocess.call(['gtk4-update-icon-cache', '-q', '-t' ,'-f',
|
||||
subprocess.call(['gtk-update-icon-cache', '-q', '-t' ,'-f',
|
||||
os.path.join(gtk_datadir, 'icons', 'hicolor')])
|
||||
|
||||
print('Updating module cache for print backends...')
|
||||
|
@@ -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
|
||||
|
||||
@@ -56,6 +59,12 @@
|
||||
/* Define if GStreamer support is available */
|
||||
#mesondefine HAVE_GSTREAMER
|
||||
|
||||
/* Define to 1 if you have the `httpGetAuthString' function. */
|
||||
#mesondefine HAVE_HTTPGETAUTHSTRING
|
||||
|
||||
/* Define if cups http_t authstring field is accessible */
|
||||
#mesondefine HAVE_HTTP_AUTHSTRING
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#mesondefine HAVE_INTTYPES_H
|
||||
|
||||
@@ -125,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
|
||||
|
||||
@@ -185,6 +191,9 @@
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#mesondefine LT_OBJDIR
|
||||
|
||||
/* Define if <X11/extensions/XIproto.h> needed for xReply */
|
||||
#mesondefine NEED_XIPROTO_H_FOR_XREPLY
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
#mesondefine NO_MINUS_C_MINUS_O
|
||||
|
||||
@@ -235,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
|
||||
|
||||
@@ -288,10 +300,18 @@
|
||||
|
||||
#mesondefine GTK_PRINT_BACKENDS
|
||||
|
||||
#mesondefine HAVE_CAIRO_SCRIPT_INTERPRETER
|
||||
|
||||
#mesondefine HAVE_HARFBUZZ
|
||||
|
||||
#mesondefine HAVE_PANGOFT
|
||||
|
||||
#mesondefine ISO_CODES_PREFIX
|
||||
|
||||
#mesondefine MALLOC_IS_ALIGNED16
|
||||
|
||||
#mesondefine HAVE_POSIX_MEMALIGN
|
||||
|
||||
#mesondefine HAVE_MEMALIGN
|
||||
|
||||
#mesondefine HAVE_ALIGNED_ALLOC
|
||||
|
||||
#mesondefine HAVE__ALIGNED_MALLOC
|
||||
|
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor-application.h"
|
||||
#include "constraint-editor-window.h"
|
||||
|
||||
struct _ConstraintEditorApplication
|
||||
{
|
||||
GtkApplication parent_instance;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditorApplication, constraint_editor_application, GTK_TYPE_APPLICATION);
|
||||
|
||||
static void
|
||||
constraint_editor_application_init (ConstraintEditorApplication *app)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
quit_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
{
|
||||
g_application_quit (G_APPLICATION (data));
|
||||
}
|
||||
|
||||
static GActionEntry app_entries[] =
|
||||
{
|
||||
{ "quit", quit_activated, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
constraint_editor_application_startup (GApplication *app)
|
||||
{
|
||||
const char *quit_accels[2] = { "<Ctrl>Q", NULL };
|
||||
const char *open_accels[2] = { "<Ctrl>O", NULL };
|
||||
GtkCssProvider *provider;
|
||||
|
||||
G_APPLICATION_CLASS (constraint_editor_application_parent_class)->startup (app);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
app);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "app.quit", quit_accels);
|
||||
gtk_application_set_accels_for_action (GTK_APPLICATION (app), "win.open", open_accels);
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider, "/org/gtk/gtk4/constraint-editor/constraint-editor.css");
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER (provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_activate (GApplication *app)
|
||||
{
|
||||
ConstraintEditorWindow *win;
|
||||
|
||||
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_open (GApplication *app,
|
||||
GFile **files,
|
||||
gint n_files,
|
||||
const gchar *hint)
|
||||
{
|
||||
ConstraintEditorWindow *win;
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; i++)
|
||||
{
|
||||
win = constraint_editor_window_new (CONSTRAINT_EDITOR_APPLICATION (app));
|
||||
constraint_editor_window_load (win, files[i]);
|
||||
gtk_window_present (GTK_WINDOW (win));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_application_class_init (ConstraintEditorApplicationClass *class)
|
||||
{
|
||||
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
||||
|
||||
application_class->startup = constraint_editor_application_startup;
|
||||
application_class->activate = constraint_editor_application_activate;
|
||||
application_class->open = constraint_editor_application_open;
|
||||
}
|
||||
|
||||
ConstraintEditorApplication *
|
||||
constraint_editor_application_new (void)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_APPLICATION_TYPE,
|
||||
"application-id", "org.gtk.gtk4.ConstraintEditor",
|
||||
"flags", G_APPLICATION_HANDLES_OPEN,
|
||||
NULL);
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_EDITOR_APPLICATION_TYPE (constraint_editor_application_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditorApplication, constraint_editor_application, CONSTRAINT, EDITOR_APPLICATION, GtkApplication)
|
||||
|
||||
ConstraintEditorApplication *constraint_editor_application_new (void);
|
@@ -1,639 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor-window.h"
|
||||
#include "constraint-view.h"
|
||||
#include "constraint-editor.h"
|
||||
#include "guide-editor.h"
|
||||
|
||||
struct _ConstraintEditorWindow
|
||||
{
|
||||
GtkApplicationWindow parent_instance;
|
||||
|
||||
GtkWidget *paned;
|
||||
GtkWidget *view;
|
||||
GtkWidget *list;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditorWindow, constraint_editor_window, GTK_TYPE_APPLICATION_WINDOW);
|
||||
|
||||
static GtkConstraintTarget *
|
||||
find_target (GListModel *model,
|
||||
GtkConstraintTarget *orig)
|
||||
{
|
||||
const char *name;
|
||||
const char *model_name;
|
||||
gpointer item;
|
||||
int i;
|
||||
|
||||
if (orig == NULL)
|
||||
return NULL;
|
||||
|
||||
if (GTK_IS_LABEL (orig))
|
||||
name = gtk_label_get_label (GTK_LABEL (orig));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (orig))
|
||||
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (orig));
|
||||
else
|
||||
{
|
||||
g_warning ("Don't know how to handle %s targets", G_OBJECT_TYPE_NAME (orig));
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
item = g_list_model_get_item (model, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_WIDGET (item))
|
||||
model_name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||
else
|
||||
model_name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||
|
||||
if (strcmp (name, model_name) == 0)
|
||||
return GTK_CONSTRAINT_TARGET (item);
|
||||
}
|
||||
g_warning ("Failed to find target '%s'", name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||
GFile *file)
|
||||
{
|
||||
char *path;
|
||||
GtkBuilder *builder;
|
||||
GError *error = NULL;
|
||||
GtkWidget *view;
|
||||
GtkLayoutManager *layout;
|
||||
GtkWidget *child;
|
||||
const char *name;
|
||||
gpointer item;
|
||||
int i;
|
||||
GListModel *list;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
|
||||
builder = gtk_builder_new ();
|
||||
if (!gtk_builder_add_from_file (builder, path, &error))
|
||||
{
|
||||
g_print ("Could not load %s: %s", path, error->message);
|
||||
g_error_free (error);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
view = GTK_WIDGET (gtk_builder_get_object (builder, "view"));
|
||||
if (!GTK_IS_BOX (view))
|
||||
{
|
||||
g_print ("Could not load %s: No GtkBox named 'view'", path);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
layout = gtk_widget_get_layout_manager (view);
|
||||
if (!GTK_IS_CONSTRAINT_LAYOUT (layout))
|
||||
{
|
||||
g_print ("Could not load %s: Widget 'view' does not use GtkConstraintLayout", path);
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (child = gtk_widget_get_first_child (view);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
if (!GTK_IS_LABEL (child))
|
||||
{
|
||||
g_print ("Skipping non-GtkLabel child\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
name = gtk_label_get_label (GTK_LABEL (child));
|
||||
constraint_view_add_child (CONSTRAINT_VIEW (self->view), name);
|
||||
}
|
||||
|
||||
list = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (layout));
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
GtkConstraintGuide *guide, *clone;
|
||||
int w, h;
|
||||
|
||||
item = g_list_model_get_item (list, i);
|
||||
guide = GTK_CONSTRAINT_GUIDE (item);
|
||||
|
||||
/* need to clone here, to attach to the right targets */
|
||||
clone = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (clone, gtk_constraint_guide_get_name (guide));
|
||||
gtk_constraint_guide_set_strength (clone, gtk_constraint_guide_get_strength (guide));
|
||||
gtk_constraint_guide_get_min_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_min_size (clone, w, h);
|
||||
gtk_constraint_guide_get_nat_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_nat_size (clone, w, h);
|
||||
gtk_constraint_guide_get_max_size (guide, &w, &h);
|
||||
gtk_constraint_guide_set_max_size (clone, w, h);
|
||||
constraint_view_add_guide (CONSTRAINT_VIEW (self->view), clone);
|
||||
g_object_unref (guide);
|
||||
g_object_unref (clone);
|
||||
}
|
||||
g_object_unref (list);
|
||||
|
||||
list = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (layout));
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
GtkConstraint *constraint;
|
||||
GtkConstraint *clone;
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintTarget *source;
|
||||
|
||||
item = g_list_model_get_item (list, i);
|
||||
constraint = GTK_CONSTRAINT (item);
|
||||
|
||||
target = gtk_constraint_get_target (constraint);
|
||||
source = gtk_constraint_get_source (constraint);
|
||||
clone = gtk_constraint_new (find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), target),
|
||||
gtk_constraint_get_target_attribute (constraint),
|
||||
gtk_constraint_get_relation (constraint),
|
||||
find_target (constraint_view_get_model (CONSTRAINT_VIEW (self->view)), source),
|
||||
gtk_constraint_get_target_attribute (constraint),
|
||||
gtk_constraint_get_multiplier (constraint),
|
||||
gtk_constraint_get_constant (constraint),
|
||||
gtk_constraint_get_strength (constraint));
|
||||
|
||||
constraint_view_add_constraint (CONSTRAINT_VIEW (self->view), clone);
|
||||
|
||||
g_object_unref (constraint);
|
||||
g_object_unref (clone);
|
||||
}
|
||||
g_object_unref (list);
|
||||
|
||||
g_free (path);
|
||||
g_object_unref (builder);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
open_response_cb (GtkNativeDialog *dialog,
|
||||
gint response,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
gtk_native_dialog_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||||
constraint_editor_window_load (self, file);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
open_cb (GtkWidget *button,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
GtkFileChooserNative *dialog;
|
||||
|
||||
dialog = gtk_file_chooser_native_new ("Open file",
|
||||
GTK_WINDOW (self),
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
"_Load",
|
||||
"_Cancel");
|
||||
|
||||
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (open_response_cb), self);
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_child (GString *str,
|
||||
int indent,
|
||||
GtkWidget *child)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = gtk_widget_get_name (child);
|
||||
g_string_append_printf (str, "%*s<child>\n", indent, "");
|
||||
g_string_append_printf (str, "%*s <object class=\"GtkLabel\" id=\"%s\">\n", indent, "", name);
|
||||
g_string_append_printf (str, "%*s <property name=\"label\">%s</property>\n", indent, "", name);
|
||||
g_string_append_printf (str, "%*s </object>\n", indent, "");
|
||||
g_string_append_printf (str, "%*s</child>\n", indent, "");
|
||||
}
|
||||
|
||||
static char *
|
||||
serialize_model (GListModel *list)
|
||||
{
|
||||
GString *str = g_string_new ("");
|
||||
int i;
|
||||
|
||||
g_string_append (str, "<interface>\n");
|
||||
g_string_append (str, " <object class=\"GtkBox\" id=\"view\">\n");
|
||||
g_string_append (str, " <property name=\"layout-manager\">\n");
|
||||
g_string_append (str, " <object class=\"GtkConstraintLayout\">\n");
|
||||
g_string_append (str, " <constraints>\n");
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (list, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
constraint_editor_serialize_constraint (str, 10, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
guide_editor_serialize_guide (str, 10, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
g_string_append (str, " </constraints>\n");
|
||||
g_string_append (str, " </object>\n");
|
||||
g_string_append (str, " </property>\n");
|
||||
for (i = 0; i < g_list_model_get_n_items (list); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (list, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_WIDGET (item))
|
||||
serialize_child (str, 4, GTK_WIDGET (item));
|
||||
}
|
||||
g_string_append (str, " </object>\n");
|
||||
g_string_append (str, "</interface>\n");
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
save_response_cb (GtkNativeDialog *dialog,
|
||||
gint response,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
gtk_native_dialog_hide (dialog);
|
||||
|
||||
if (response == GTK_RESPONSE_ACCEPT)
|
||||
{
|
||||
GListModel *model;
|
||||
char *text, *filename;
|
||||
GError *error = NULL;
|
||||
|
||||
model = constraint_view_get_model (CONSTRAINT_VIEW (self->view));
|
||||
text = serialize_model (model);
|
||||
|
||||
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||
if (!g_file_set_contents (filename, text, -1, &error))
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (self))),
|
||||
GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
GTK_BUTTONS_OK,
|
||||
"Saving failed");
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||||
"%s", error->message);
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (dialog);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
gtk_native_dialog_destroy (dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
save_cb (GtkWidget *button,
|
||||
ConstraintEditorWindow *self)
|
||||
{
|
||||
GtkFileChooserNative *dialog;
|
||||
|
||||
dialog = gtk_file_chooser_native_new ("Save constraints",
|
||||
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (button))),
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
"_Save",
|
||||
"_Cancel");
|
||||
|
||||
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), ".");
|
||||
g_signal_connect (dialog, "response", G_CALLBACK (save_response_cb), self);
|
||||
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_finalize (GObject *object)
|
||||
{
|
||||
//ConstraintEditorWindow *self = (ConstraintEditorWindow *)object;
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_window_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static int child_counter;
|
||||
static int guide_counter;
|
||||
|
||||
static void
|
||||
add_child (ConstraintEditorWindow *win)
|
||||
{
|
||||
char *name;
|
||||
|
||||
child_counter++;
|
||||
name = g_strdup_printf ("Child %d", child_counter);
|
||||
constraint_view_add_child (CONSTRAINT_VIEW (win->view), name);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
static void
|
||||
add_guide (ConstraintEditorWindow *win)
|
||||
{
|
||||
char *name;
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
guide_counter++;
|
||||
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||
guide = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (guide, name);
|
||||
g_free (name);
|
||||
|
||||
constraint_view_add_guide (CONSTRAINT_VIEW (win->view), guide);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_done (ConstraintEditor *editor,
|
||||
GtkConstraint *constraint,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkConstraint *old_constraint;
|
||||
|
||||
g_object_get (editor, "constraint", &old_constraint, NULL);
|
||||
|
||||
if (old_constraint)
|
||||
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view), old_constraint);
|
||||
|
||||
constraint_view_add_constraint (CONSTRAINT_VIEW (win->view), constraint);
|
||||
|
||||
g_clear_object (&old_constraint);
|
||||
|
||||
gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
|
||||
}
|
||||
|
||||
static void
|
||||
edit_constraint (ConstraintEditorWindow *win,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkWidget *window;
|
||||
ConstraintEditor *editor;
|
||||
GListModel *model;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
if (constraint)
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Edit Constraint");
|
||||
else
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Create Constraint");
|
||||
|
||||
model = constraint_view_get_model (CONSTRAINT_VIEW (win->view));
|
||||
|
||||
editor = constraint_editor_new (model, constraint);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (constraint_editor_done), win);
|
||||
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
add_constraint (ConstraintEditorWindow *win)
|
||||
{
|
||||
edit_constraint (win, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_done (GuideEditor *editor,
|
||||
GtkConstraintGuide *guide,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
gtk_widget_destroy (gtk_widget_get_ancestor (GTK_WIDGET (editor), GTK_TYPE_WINDOW));
|
||||
}
|
||||
|
||||
static void
|
||||
edit_guide (ConstraintEditorWindow *win,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GuideEditor *editor;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (win));
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Edit Guide");
|
||||
|
||||
editor = guide_editor_new (guide);
|
||||
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (editor));
|
||||
|
||||
g_signal_connect (editor, "done", G_CALLBACK (guide_editor_done), win);
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
|
||||
static void
|
||||
row_activated (GtkListBox *list,
|
||||
GtkListBoxRow *row,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GObject *item;
|
||||
|
||||
item = G_OBJECT (g_object_get_data (G_OBJECT (row), "item"));
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_class_init (ConstraintEditorWindowClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
g_type_ensure (CONSTRAINT_VIEW_TYPE);
|
||||
|
||||
object_class->finalize = constraint_editor_window_finalize;
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/constraint-editor-window.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, paned);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, view);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditorWindow, list);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, open_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, save_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_child);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_guide);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_constraint);
|
||||
gtk_widget_class_bind_template_callback (widget_class, row_activated);
|
||||
}
|
||||
|
||||
static void
|
||||
row_edit (GtkButton *button,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkWidget *row;
|
||||
GObject *item;
|
||||
|
||||
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
edit_constraint (win, GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
edit_guide (win, GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
|
||||
static void
|
||||
mark_constraints_invalid (ConstraintEditorWindow *win,
|
||||
gpointer removed)
|
||||
{
|
||||
GtkWidget *child;
|
||||
GObject *item;
|
||||
|
||||
for (child = gtk_widget_get_first_child (win->list);
|
||||
child;
|
||||
child = gtk_widget_get_next_sibling (child))
|
||||
{
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (child), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
{
|
||||
GtkConstraint *constraint = GTK_CONSTRAINT (item);
|
||||
|
||||
if (gtk_constraint_get_target (constraint) == (GtkConstraintTarget *)removed ||
|
||||
gtk_constraint_get_source (constraint) == (GtkConstraintTarget *)removed)
|
||||
{
|
||||
GtkWidget *button;
|
||||
button = (GtkWidget *)g_object_get_data (G_OBJECT (child), "edit");
|
||||
gtk_button_set_icon_name (GTK_BUTTON (button), "dialog-warning-symbolic");
|
||||
gtk_widget_set_tooltip_text (button, "Constraint is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
row_delete (GtkButton *button,
|
||||
ConstraintEditorWindow *win)
|
||||
{
|
||||
GtkWidget *row;
|
||||
GObject *item;
|
||||
|
||||
row = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_LIST_BOX_ROW);
|
||||
item = (GObject *)g_object_get_data (G_OBJECT (row), "item");
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
constraint_view_remove_constraint (CONSTRAINT_VIEW (win->view),
|
||||
GTK_CONSTRAINT (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
mark_constraints_invalid (win, item);
|
||||
constraint_view_remove_guide (CONSTRAINT_VIEW (win->view),
|
||||
GTK_CONSTRAINT_GUIDE (item));
|
||||
}
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
mark_constraints_invalid (win, item);
|
||||
constraint_view_remove_child (CONSTRAINT_VIEW (win->view),
|
||||
GTK_WIDGET (item));
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_widget_func (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
ConstraintEditorWindow *win = user_data;
|
||||
const char *name;
|
||||
char *freeme = NULL;
|
||||
GtkWidget *row, *box, *label, *button;
|
||||
|
||||
if (GTK_IS_WIDGET (item))
|
||||
name = gtk_widget_get_name (GTK_WIDGET (item));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
name = gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item));
|
||||
else if (GTK_IS_CONSTRAINT (item))
|
||||
name = freeme = constraint_editor_constraint_to_string (GTK_CONSTRAINT (item));
|
||||
else
|
||||
name = "";
|
||||
|
||||
row = gtk_list_box_row_new ();
|
||||
g_object_set_data_full (G_OBJECT (row), "item", g_object_ref (item), g_object_unref);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
label = gtk_label_new (name);
|
||||
if (GTK_IS_WIDGET (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
g_object_bind_property (item, "name",
|
||||
label, "label",
|
||||
G_BINDING_DEFAULT);
|
||||
g_object_set (label, "margin", 10, NULL);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item) || GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("document-edit-symbolic");
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_edit), win);
|
||||
g_object_set_data (G_OBJECT (row), "edit", button);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
}
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
button = gtk_button_new_from_icon_name ("edit-delete-symbolic");
|
||||
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
|
||||
g_signal_connect (button, "clicked", G_CALLBACK (row_delete), win);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
}
|
||||
|
||||
g_free (freeme);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_window_init (ConstraintEditorWindow *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
|
||||
gtk_list_box_bind_model (GTK_LIST_BOX (self->list),
|
||||
constraint_view_get_model (CONSTRAINT_VIEW (self->view)),
|
||||
create_widget_func,
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
ConstraintEditorWindow *
|
||||
constraint_editor_window_new (ConstraintEditorApplication *application)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_WINDOW_TYPE,
|
||||
"application", application,
|
||||
NULL);
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "constraint-editor-application.h"
|
||||
|
||||
|
||||
#define CONSTRAINT_EDITOR_WINDOW_TYPE (constraint_editor_window_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditorWindow, constraint_editor_window, CONSTRAINT, EDITOR_WINDOW, GtkApplicationWindow)
|
||||
|
||||
ConstraintEditorWindow * constraint_editor_window_new (ConstraintEditorApplication *application);
|
||||
|
||||
gboolean constraint_editor_window_load (ConstraintEditorWindow *self,
|
||||
GFile *file);
|
@@ -1,82 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ConstraintEditorWindow" parent="GtkApplicationWindow">
|
||||
<style>
|
||||
<class name="devel"/>
|
||||
</style>
|
||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||
<property name="default-width">1024</property>
|
||||
<property name="default-height">768</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="title" translatable="yes">GTK Constraint Editor</property>
|
||||
<property name="show-title-buttons">1</property>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-open-symbolic</property>
|
||||
<property name="tooltip-text">Open ui file</property>
|
||||
<signal name="clicked" handler="open_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="start">
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">document-save-symbolic</property>
|
||||
<property name="tooltip-text">Save to ui file</property>
|
||||
<signal name="clicked" handler="save_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkPaned" id="paned">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">horizontal</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Child</property>
|
||||
<signal name="clicked" handler="add_child" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Guide</property>
|
||||
<signal name="clicked" handler="add_guide" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="label">Add Constraint</property>
|
||||
<signal name="clicked" handler="add_constraint" swapped="yes"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vscrollbar-policy">automatic</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkListBox" id="list">
|
||||
<property name="show-separators">1</property>
|
||||
<property name="selection-mode">none</property>
|
||||
<signal name="row-activated" handler="row_activated"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="ConstraintView" id="view">
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@@ -1,656 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "constraint-editor.h"
|
||||
|
||||
struct _ConstraintEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *grid;
|
||||
GtkWidget *target;
|
||||
GtkWidget *target_attr;
|
||||
GtkWidget *relation;
|
||||
GtkWidget *source;
|
||||
GtkWidget *source_attr;
|
||||
GtkWidget *multiplier;
|
||||
GtkWidget *constant;
|
||||
GtkWidget *strength;
|
||||
GtkWidget *preview;
|
||||
GtkWidget *button;
|
||||
|
||||
GtkConstraint *constraint;
|
||||
GListModel *model;
|
||||
|
||||
gboolean constructed;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_MODEL = 1,
|
||||
PROP_CONSTRAINT,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *pspecs[LAST_PROP];
|
||||
|
||||
enum {
|
||||
DONE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(ConstraintEditor, constraint_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static const char *
|
||||
get_target_name (GtkConstraintTarget *target)
|
||||
{
|
||||
if (target == NULL)
|
||||
return "super";
|
||||
else if (GTK_IS_WIDGET (target))
|
||||
return gtk_widget_get_name (GTK_WIDGET (target));
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (target))
|
||||
return gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (target));
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_target_combo (GListModel *model,
|
||||
GtkWidget *combo,
|
||||
gboolean is_source)
|
||||
{
|
||||
int i;
|
||||
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "super", "Super");
|
||||
|
||||
if (model)
|
||||
{
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GObject *item = g_list_model_get_object (model, i);
|
||||
const char *name;
|
||||
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
continue;
|
||||
|
||||
name = get_target_name (GTK_CONSTRAINT_TARGET (item));
|
||||
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), name, name);
|
||||
g_object_unref (item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_attribute_combo (GtkWidget *combo,
|
||||
gboolean is_source)
|
||||
{
|
||||
if (is_source)
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "none", "None");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "left", "Left");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "right", "Right");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "top", "Top");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "bottom", "Bottom");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "start", "Start");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "end", "End");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "width", "Width");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "height", "Height");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-x", "Center X");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center-y", "Center Y");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "baseline", "Baseline");
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_relation_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "le", "≤");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "eq", "=");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "ge", "≥");
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_strength_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||
}
|
||||
|
||||
static gpointer
|
||||
get_target (GListModel *model,
|
||||
const char *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (strcmp ("super", id) == 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (model); i++)
|
||||
{
|
||||
GObject *item = g_list_model_get_object (model, i);
|
||||
g_object_unref (item);
|
||||
if (GTK_IS_CONSTRAINT (item))
|
||||
continue;
|
||||
else if (GTK_IS_WIDGET (item))
|
||||
{
|
||||
if (strcmp (id, gtk_widget_get_name (GTK_WIDGET (item))) == 0)
|
||||
return item;
|
||||
}
|
||||
else if (GTK_IS_CONSTRAINT_GUIDE (item))
|
||||
{
|
||||
if (strcmp (id, gtk_constraint_guide_get_name (GTK_CONSTRAINT_GUIDE (item))) == 0)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GtkConstraintAttribute
|
||||
get_target_attr (const char *id)
|
||||
{
|
||||
GtkConstraintAttribute attr;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
attr = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_attr_nick (GtkConstraintAttribute attr)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_ATTRIBUTE);
|
||||
GEnumValue *value = g_enum_get_value (class, attr);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
static GtkConstraintRelation
|
||||
get_relation (const char *id)
|
||||
{
|
||||
GtkConstraintRelation relation;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
relation = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return relation;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_relation_nick (GtkConstraintRelation relation)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_RELATION);
|
||||
GEnumValue *value = g_enum_get_value (class, relation);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (const char *id)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
strength = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return strength;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_strength_nick (GtkConstraintStrength strength)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value (class, strength);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
void
|
||||
constraint_editor_serialize_constraint (GString *str,
|
||||
int indent,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
const char *target;
|
||||
const char *target_attr;
|
||||
const char *relation;
|
||||
const char *source;
|
||||
const char *source_attr;
|
||||
double multiplier;
|
||||
double constant;
|
||||
const char *strength;
|
||||
|
||||
target = get_target_name (gtk_constraint_get_target (constraint));
|
||||
target_attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||
source = get_target_name (gtk_constraint_get_source (constraint));
|
||||
source_attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||
multiplier = gtk_constraint_get_multiplier (constraint);
|
||||
constant = gtk_constraint_get_constant (constraint);
|
||||
strength = get_strength_nick (gtk_constraint_get_strength (constraint));
|
||||
|
||||
g_string_append_printf (str, "%*s<constraint target=\"%s\" target-attribute=\"%s\"\n", indent, "", target, target_attr);
|
||||
g_string_append_printf (str, "%*s relation=\"%s\"\n", indent, "", relation);
|
||||
if (strcmp (source_attr, "none") != 0)
|
||||
{
|
||||
g_string_append_printf (str, "%*s source=\"%s\" source-attribute=\"%s\"\n", indent, "", source, source_attr);
|
||||
g_string_append_printf (str, "%*s multiplier=\"%g\"\n", indent, "", multiplier);
|
||||
}
|
||||
g_string_append_printf (str, "%*s constant=\"%g\"\n", indent, "", constant);
|
||||
g_string_append_printf (str, "%*s strength=\"%s\" />\n", indent, "", strength);
|
||||
}
|
||||
|
||||
static void
|
||||
create_constraint (GtkButton *button,
|
||||
ConstraintEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
gpointer target;
|
||||
GtkConstraintAttribute target_attr;
|
||||
gpointer source;
|
||||
GtkConstraintAttribute source_attr;
|
||||
GtkConstraintRelation relation;
|
||||
double multiplier;
|
||||
double constant;
|
||||
int strength;
|
||||
GtkConstraint *constraint;
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||
target = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||
target_attr = get_target_attr (id);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
source = get_target (editor->model, id);
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
source_attr = get_target_attr (id);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->relation));
|
||||
relation = get_relation (id);
|
||||
|
||||
multiplier = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->multiplier)), NULL);
|
||||
|
||||
constant = g_ascii_strtod (gtk_editable_get_text (GTK_EDITABLE (editor->constant)), NULL);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||
strength = get_strength (id);
|
||||
|
||||
constraint = gtk_constraint_new (target, target_attr,
|
||||
relation,
|
||||
source, source_attr,
|
||||
multiplier,
|
||||
constant,
|
||||
strength);
|
||||
g_signal_emit (editor, signals[DONE], 0, constraint);
|
||||
g_object_unref (constraint);
|
||||
}
|
||||
|
||||
static void
|
||||
source_attr_changed (ConstraintEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
if (strcmp (id, "none") == 0)
|
||||
{
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (editor->source), -1);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "");
|
||||
gtk_widget_set_sensitive (editor->source, FALSE);
|
||||
gtk_widget_set_sensitive (editor->multiplier, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_set_sensitive (editor->source, TRUE);
|
||||
gtk_widget_set_sensitive (editor->multiplier, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
constraint_editor_constraint_to_string (GtkConstraint *constraint)
|
||||
{
|
||||
GString *str;
|
||||
const char *name;
|
||||
const char *attr;
|
||||
const char *relation;
|
||||
double c, m;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
name = get_target_name (gtk_constraint_get_target (constraint));
|
||||
attr = get_attr_nick (gtk_constraint_get_target_attribute (constraint));
|
||||
relation = get_relation_nick (gtk_constraint_get_relation (constraint));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||
|
||||
c = gtk_constraint_get_constant (constraint);
|
||||
|
||||
attr = get_attr_nick (gtk_constraint_get_source_attribute (constraint));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = get_target_name (gtk_constraint_get_source (constraint));
|
||||
m = gtk_constraint_get_multiplier (constraint);
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s", name, attr);
|
||||
|
||||
if (m != 1.0)
|
||||
g_string_append_printf (str, " × %g", m);
|
||||
|
||||
if (c > 0.0)
|
||||
g_string_append_printf (str, " + %g", c);
|
||||
else if (c < 0.0)
|
||||
g_string_append_printf (str, " - %g", -c);
|
||||
}
|
||||
else
|
||||
g_string_append_printf (str, "%g", c);
|
||||
|
||||
return g_string_free (str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_preview (ConstraintEditor *editor)
|
||||
{
|
||||
GString *str;
|
||||
const char *name;
|
||||
const char *attr;
|
||||
char *relation;
|
||||
const char *multiplier;
|
||||
const char *constant;
|
||||
double c, m;
|
||||
|
||||
if (!editor->constructed)
|
||||
return;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target));
|
||||
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target_attr));
|
||||
relation = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (editor->relation));
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s %s ", name, attr, relation);
|
||||
g_free (relation);
|
||||
|
||||
constant = gtk_editable_get_text (GTK_EDITABLE (editor->constant));
|
||||
c = g_ascii_strtod (constant, NULL);
|
||||
|
||||
attr = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source_attr));
|
||||
if (strcmp (attr, "none") != 0)
|
||||
{
|
||||
name = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source));
|
||||
multiplier = gtk_editable_get_text (GTK_EDITABLE (editor->multiplier));
|
||||
m = g_ascii_strtod (multiplier, NULL);
|
||||
|
||||
if (name == NULL)
|
||||
name = "[ ]";
|
||||
|
||||
g_string_append_printf (str, "%s.%s", name, attr);
|
||||
|
||||
if (m != 1.0)
|
||||
g_string_append_printf (str, " × %g", m);
|
||||
|
||||
if (c > 0.0)
|
||||
g_string_append_printf (str, " + %g", c);
|
||||
else if (c < 0.0)
|
||||
g_string_append_printf (str, " - %g", -c);
|
||||
}
|
||||
else
|
||||
g_string_append_printf (str, "%g", c);
|
||||
|
||||
gtk_label_set_label (GTK_LABEL (editor->preview), str->str);
|
||||
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_button (ConstraintEditor *editor)
|
||||
{
|
||||
if (gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->target)) != NULL &&
|
||||
gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->source)) != NULL)
|
||||
gtk_widget_set_sensitive (editor->button, TRUE);
|
||||
else
|
||||
gtk_widget_set_sensitive (editor->button, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_init (ConstraintEditor *editor)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_constructed (GObject *object)
|
||||
{
|
||||
ConstraintEditor *editor = CONSTRAINT_EDITOR (object);
|
||||
|
||||
constraint_target_combo (editor->model, editor->target, FALSE);
|
||||
constraint_attribute_combo (editor->target_attr, FALSE);
|
||||
constraint_relation_combo (editor->relation);
|
||||
constraint_target_combo (editor->model, editor->source, TRUE);
|
||||
constraint_attribute_combo (editor->source_attr, TRUE);
|
||||
|
||||
constraint_strength_combo (editor->strength);
|
||||
|
||||
if (editor->constraint)
|
||||
{
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintAttribute attr;
|
||||
GtkConstraintRelation relation;
|
||||
GtkConstraintStrength strength;
|
||||
const char *nick;
|
||||
char *val;
|
||||
double multiplier;
|
||||
double constant;
|
||||
|
||||
target = gtk_constraint_get_target (editor->constraint);
|
||||
nick = get_target_name (target);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target), nick);
|
||||
|
||||
attr = gtk_constraint_get_target_attribute (editor->constraint);
|
||||
nick = get_attr_nick (attr);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), nick);
|
||||
|
||||
target = gtk_constraint_get_source (editor->constraint);
|
||||
nick = get_target_name (target);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source), nick);
|
||||
|
||||
attr = gtk_constraint_get_source_attribute (editor->constraint);
|
||||
nick = get_attr_nick (attr);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), nick);
|
||||
|
||||
relation = gtk_constraint_get_relation (editor->constraint);
|
||||
nick = get_relation_nick (relation);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), nick);
|
||||
|
||||
multiplier = gtk_constraint_get_multiplier (editor->constraint);
|
||||
val = g_strdup_printf ("%g", multiplier);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), val);
|
||||
g_free (val);
|
||||
|
||||
constant = gtk_constraint_get_constant (editor->constraint);
|
||||
val = g_strdup_printf ("%g", constant);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->constant), val);
|
||||
g_free (val);
|
||||
|
||||
strength = gtk_constraint_get_strength (editor->constraint);
|
||||
nick = get_strength_nick (strength);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->target_attr), "left");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->source_attr), "left");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->relation), "eq");
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "required");
|
||||
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->multiplier), "1.0");
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->constant), "0.0");
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||
}
|
||||
|
||||
editor->constructed = TRUE;
|
||||
update_preview (editor);
|
||||
update_button (editor);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
self->model = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_CONSTRAINT:
|
||||
self->constraint = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ConstraintEditor *self = CONSTRAINT_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_MODEL:
|
||||
g_value_set_object (value, self->model);
|
||||
break;
|
||||
|
||||
case PROP_CONSTRAINT:
|
||||
g_value_set_object (value, self->constraint);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_dispose (GObject *object)
|
||||
{
|
||||
ConstraintEditor *self = (ConstraintEditor *)object;
|
||||
|
||||
g_clear_pointer (&self->grid, gtk_widget_unparent);
|
||||
g_clear_object (&self->model);
|
||||
g_clear_object (&self->constraint);
|
||||
|
||||
G_OBJECT_CLASS (constraint_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_editor_class_init (ConstraintEditorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->constructed = constraint_editor_constructed;
|
||||
object_class->dispose = constraint_editor_dispose;
|
||||
object_class->set_property = constraint_editor_set_property;
|
||||
object_class->get_property = constraint_editor_get_property;
|
||||
|
||||
pspecs[PROP_CONSTRAINT] =
|
||||
g_param_spec_object ("constraint", "constraint", "constraint",
|
||||
GTK_TYPE_CONSTRAINT,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
pspecs[PROP_MODEL] =
|
||||
g_param_spec_object ("model", "model", "model",
|
||||
G_TYPE_LIST_MODEL,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||
|
||||
signals[DONE] =
|
||||
g_signal_new ("done",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/constraint-editor.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, grid);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, target_attr);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, relation);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, source_attr);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, multiplier);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, constant);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, strength);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, preview);
|
||||
gtk_widget_class_bind_template_child (widget_class, ConstraintEditor, button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_preview);
|
||||
gtk_widget_class_bind_template_callback (widget_class, update_button);
|
||||
gtk_widget_class_bind_template_callback (widget_class, create_constraint);
|
||||
gtk_widget_class_bind_template_callback (widget_class, source_attr_changed);
|
||||
}
|
||||
|
||||
ConstraintEditor *
|
||||
constraint_editor_new (GListModel *model,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_EDITOR_TYPE,
|
||||
"model", model,
|
||||
"constraint", constraint,
|
||||
NULL);
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
constraintview {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
constraintview .child {
|
||||
background: red;
|
||||
}
|
||||
|
||||
constraintview .guide {
|
||||
background: blue;
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/org/gtk/gtk4/constraint-editor">
|
||||
<file preprocess="xml-stripblanks">constraint-editor-window.ui</file>
|
||||
<file preprocess="xml-stripblanks">constraint-editor.ui</file>
|
||||
<file preprocess="xml-stripblanks">guide-editor.ui</file>
|
||||
<file>constraint-editor.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_EDITOR_TYPE (constraint_editor_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintEditor, constraint_editor, CONSTRAINT, EDITOR, GtkWidget)
|
||||
|
||||
ConstraintEditor * constraint_editor_new (GListModel *model,
|
||||
GtkConstraint *constraint);
|
||||
|
||||
void constraint_editor_serialize_constraint (GString *str,
|
||||
int indent,
|
||||
GtkConstraint *constraint);
|
||||
char *constraint_editor_constraint_to_string (GtkConstraint *constraint);
|
@@ -1,163 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="ConstraintEditor" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<property name="margin">20</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Target</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="target">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="target_attr">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Relation</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="relation">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Source</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="source">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="update_button" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="source_attr">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<signal name="changed" handler="source_attr_changed" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Multiplier</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="multiplier">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Constant</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="constant">
|
||||
<signal name="changed" handler="update_preview" swapped="yes"/>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Strength</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="strength">
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="preview">
|
||||
<property name="xalign">0</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">7</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
<attributes>
|
||||
<attribute name="scale" value="1.44"/>
|
||||
</attributes>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="label">Create</property>
|
||||
<signal name="clicked" handler="create_constraint"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">8</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "constraint-view-child.h"
|
||||
|
||||
struct _ConstraintViewChild
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_NAME = 1,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec props[LAST_PROP];
|
||||
|
||||
G_DEFINE_TYPE (ConstraintViewChild, constraint_view_child, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
constraint_view_child_init (ConstraintViewChild *child)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_child_finalize (GObject *object)
|
||||
{
|
||||
ConstraintViewChild *child = CONSTRAINT_VIEW_CHILD (object);
|
||||
|
||||
g_free (child->name);
|
||||
|
||||
G_OBJECT_CLASS (constraint_view_child_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_child_set_property (GObject *object,
|
||||
|
||||
static void
|
||||
constraint_view_child_class_init (ConstraintViewChildClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = constraint_view_child_finalize;
|
||||
object_class->get_property = constraint_view_child_get_property;
|
||||
object_class->set_property = constraint_view_child_set_property;
|
||||
|
||||
props[PROP_NAME] =
|
||||
g_param_spec_string ("name", "name", "name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, props);
|
||||
}
|
||||
|
||||
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||
|
||||
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||
|
||||
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_constraint_new (void);
|
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_VIEW_CHILD_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_TYPE (ConstraintViewChild, constraint_view_child, CONSTRAINT, VIEW_CHILD, GObject)
|
||||
|
||||
#define CONSTRAINT_VIEW_WIDGET_TYPE (constraint_view_widget_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewWidget, constraint_view_widget, CONSTRAINT, VIEW_WIDGET, ConstraintViewChild)
|
||||
|
||||
ConstraintViewWidget * constraint_view_widget_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_GUIDE_TYPE (constraint_view_guide_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewGuide, constraint_view_guide, CONSTRAINT, VIEW_GUIDE, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_guide_new (void);
|
||||
|
||||
#define CONSTRAINT_VIEW_CONSTRAINT_TYPE (constraint_view_constraint_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintViewConstraint, constraint_view_constraint, CONSTRAINT, VIEW_CONSTRAINT, ConstraintViewChild)
|
||||
|
||||
ConstraintViewGuide * constraint_view_constraint_new (void);
|
@@ -1,343 +0,0 @@
|
||||
/* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "constraint-view.h"
|
||||
|
||||
struct _ConstraintView
|
||||
{
|
||||
GtkWidget parent;
|
||||
|
||||
GListModel *model;
|
||||
|
||||
GtkWidget *drag_widget;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ConstraintView, constraint_view, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
constraint_view_dispose (GObject *object)
|
||||
{
|
||||
ConstraintView *view = CONSTRAINT_VIEW (object);
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (view))) != NULL)
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
g_clear_object (&view->model);
|
||||
|
||||
G_OBJECT_CLASS (constraint_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_class_init (ConstraintViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = constraint_view_dispose;
|
||||
|
||||
gtk_widget_class_set_css_name (widget_class, "constraintview");
|
||||
}
|
||||
|
||||
static void
|
||||
update_weak_position (ConstraintView *self,
|
||||
GtkWidget *child,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
GtkConstraint *constraint;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "x-constraint");
|
||||
if (constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "x-constraint", NULL);
|
||||
}
|
||||
if (x != -100)
|
||||
{
|
||||
constraint = gtk_constraint_new_constant (child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
x,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "x-constraint", constraint);
|
||||
}
|
||||
|
||||
constraint = (GtkConstraint *)g_object_get_data (G_OBJECT (child), "y-constraint");
|
||||
if (constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "y-constraint", NULL);
|
||||
}
|
||||
if (y != -100)
|
||||
{
|
||||
constraint = gtk_constraint_new_constant (child,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
y,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
g_object_set_data (G_OBJECT (child), "y-constraint", constraint);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkGestureDrag *drag,
|
||||
double start_x,
|
||||
double start_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
widget = gtk_widget_pick (GTK_WIDGET (self), start_x, start_y, GTK_PICK_DEFAULT);
|
||||
|
||||
if (GTK_IS_LABEL (widget))
|
||||
{
|
||||
widget = gtk_widget_get_ancestor (widget, GTK_TYPE_FRAME);
|
||||
if (widget &&
|
||||
gtk_widget_get_parent (widget) == (GtkWidget *)self)
|
||||
{
|
||||
self->drag_widget = widget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
drag_update (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
if (!self->drag_widget)
|
||||
return;
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
||||
update_weak_position (self, self->drag_widget, x + offset_x, y + offset_y);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
ConstraintView *self)
|
||||
{
|
||||
self->drag_widget = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
omit_internal (gpointer item, gpointer user_data)
|
||||
{
|
||||
if (g_object_get_data (G_OBJECT (item), "internal"))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_view_init (ConstraintView *self)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
GtkEventController *controller;
|
||||
GListStore *list;
|
||||
GListModel *all_children;
|
||||
GListModel *all_constraints;
|
||||
GListModel *guides;
|
||||
GListModel *children;
|
||||
GListModel *constraints;
|
||||
|
||||
manager = gtk_constraint_layout_new ();
|
||||
gtk_widget_set_layout_manager (GTK_WIDGET (self), manager);
|
||||
|
||||
all_children = gtk_widget_observe_children (GTK_WIDGET (self));
|
||||
all_constraints = gtk_constraint_layout_observe_constraints (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
guides = gtk_constraint_layout_observe_guides (GTK_CONSTRAINT_LAYOUT (manager));
|
||||
constraints = (GListModel *)gtk_filter_list_model_new (all_constraints, omit_internal, NULL, NULL);
|
||||
children = (GListModel *)gtk_filter_list_model_new (all_children, omit_internal, NULL, NULL);
|
||||
|
||||
list = g_list_store_new (G_TYPE_LIST_MODEL);
|
||||
g_list_store_append (list, children);
|
||||
g_list_store_append (list, guides);
|
||||
g_list_store_append (list, constraints);
|
||||
self->model = G_LIST_MODEL (gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list)));
|
||||
g_object_unref (children);
|
||||
g_object_unref (guides);
|
||||
g_object_unref (constraints);
|
||||
g_object_unref (all_children);
|
||||
g_object_unref (all_constraints);
|
||||
g_object_unref (list);
|
||||
|
||||
|
||||
controller = (GtkEventController *)gtk_gesture_drag_new ();
|
||||
g_signal_connect (controller, "drag-begin", G_CALLBACK (drag_begin), self);
|
||||
g_signal_connect (controller, "drag-update", G_CALLBACK (drag_update), self);
|
||||
g_signal_connect (controller, "drag-end", G_CALLBACK (drag_end), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), controller);
|
||||
}
|
||||
|
||||
ConstraintView *
|
||||
constraint_view_new (void)
|
||||
{
|
||||
return g_object_new (CONSTRAINT_VIEW_TYPE, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_child (ConstraintView *view,
|
||||
const char *name)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *label;
|
||||
|
||||
label = gtk_label_new (name);
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (frame), "child");
|
||||
gtk_widget_set_name (frame, name);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_widget_set_parent (frame, GTK_WIDGET (view));
|
||||
|
||||
update_weak_position (view, frame, 100, 100);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_child (ConstraintView *view,
|
||||
GtkWidget *child)
|
||||
{
|
||||
update_weak_position (view, child, -100, -100);
|
||||
gtk_widget_unparent (child);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintLayout *layout;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *label;
|
||||
const char *name;
|
||||
GtkConstraint *constraint;
|
||||
struct {
|
||||
const char *name;
|
||||
GtkConstraintAttribute attr;
|
||||
} names[] = {
|
||||
{ "left-constraint", GTK_CONSTRAINT_ATTRIBUTE_LEFT },
|
||||
{ "top-constraint", GTK_CONSTRAINT_ATTRIBUTE_TOP },
|
||||
{ "width-constraint", GTK_CONSTRAINT_ATTRIBUTE_WIDTH },
|
||||
{ "height-constraint", GTK_CONSTRAINT_ATTRIBUTE_HEIGHT },
|
||||
};
|
||||
int i;
|
||||
|
||||
name = gtk_constraint_guide_get_name (guide);
|
||||
label = gtk_label_new (name);
|
||||
g_object_bind_property (guide, "name",
|
||||
label, "label",
|
||||
G_BINDING_DEFAULT);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (frame), "guide");
|
||||
g_object_set_data (G_OBJECT (frame), "internal", "yes");
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_widget_insert_after (frame, GTK_WIDGET (view), NULL);
|
||||
|
||||
g_object_set_data (G_OBJECT (guide), "frame", frame);
|
||||
|
||||
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||
gtk_constraint_layout_add_guide (layout, g_object_ref (guide));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
constraint = gtk_constraint_new (frame,
|
||||
names[i].attr,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
guide,
|
||||
names[i].attr,
|
||||
1.0, 0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
g_object_set_data (G_OBJECT (constraint), "internal", "yes");
|
||||
gtk_constraint_layout_add_constraint (layout, constraint);
|
||||
g_object_set_data (G_OBJECT (guide), names[i].name, constraint);
|
||||
}
|
||||
|
||||
update_weak_position (view, frame, 150, 150);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintLayout *layout;
|
||||
GtkWidget *frame;
|
||||
GtkConstraint *constraint;
|
||||
const char *names[] = {
|
||||
"left-constraint",
|
||||
"top-constraint",
|
||||
"width-constraint",
|
||||
"height-constraint"
|
||||
};
|
||||
int i;
|
||||
|
||||
layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (view)));
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (names); i++)
|
||||
{
|
||||
constraint = (GtkConstraint*)g_object_get_data (G_OBJECT (guide), names[i]);
|
||||
gtk_constraint_layout_remove_constraint (layout, constraint);
|
||||
}
|
||||
|
||||
frame = (GtkWidget *)g_object_get_data (G_OBJECT (guide), "frame");
|
||||
update_weak_position (view, frame, -100, -100);
|
||||
gtk_widget_unparent (frame);
|
||||
|
||||
gtk_constraint_layout_remove_guide (layout, guide);
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_add_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||
gtk_constraint_layout_add_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
g_object_ref (constraint));
|
||||
}
|
||||
|
||||
void
|
||||
constraint_view_remove_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint)
|
||||
{
|
||||
GtkLayoutManager *manager;
|
||||
|
||||
manager = gtk_widget_get_layout_manager (GTK_WIDGET (view));
|
||||
gtk_constraint_layout_remove_constraint (GTK_CONSTRAINT_LAYOUT (manager),
|
||||
constraint);
|
||||
}
|
||||
|
||||
GListModel *
|
||||
constraint_view_get_model (ConstraintView *view)
|
||||
{
|
||||
return view->model;
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define CONSTRAINT_VIEW_TYPE (constraint_view_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ConstraintView, constraint_view, CONSTRAINT, VIEW, GtkWidget)
|
||||
|
||||
ConstraintView * constraint_view_new (void);
|
||||
|
||||
void constraint_view_add_child (ConstraintView *view,
|
||||
const char *name);
|
||||
void constraint_view_remove_child (ConstraintView *view,
|
||||
GtkWidget *child);
|
||||
void constraint_view_add_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_remove_guide (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_guide_changed (ConstraintView *view,
|
||||
GtkConstraintGuide *guide);
|
||||
void constraint_view_add_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint);
|
||||
void constraint_view_remove_constraint (ConstraintView *view,
|
||||
GtkConstraint *constraint);
|
||||
GListModel * constraint_view_get_model (ConstraintView *view);
|
@@ -1,411 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "guide-editor.h"
|
||||
|
||||
struct _GuideEditor
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *grid;
|
||||
GtkWidget *name;
|
||||
GtkWidget *min_width;
|
||||
GtkWidget *min_height;
|
||||
GtkWidget *nat_width;
|
||||
GtkWidget *nat_height;
|
||||
GtkWidget *max_width;
|
||||
GtkWidget *max_height;
|
||||
GtkWidget *strength;
|
||||
GtkWidget *button;
|
||||
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
gboolean constructed;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_GUIDE = 1,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *pspecs[LAST_PROP];
|
||||
|
||||
enum {
|
||||
DONE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
G_DEFINE_TYPE(GuideEditor, guide_editor, GTK_TYPE_WIDGET);
|
||||
|
||||
static void
|
||||
guide_strength_combo (GtkWidget *combo)
|
||||
{
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "weak", "Weak");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "medium", "Medium");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "strong", "Strong");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "required", "Required");
|
||||
}
|
||||
|
||||
static GtkConstraintStrength
|
||||
get_strength (const char *id)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value_by_nick (class, id);
|
||||
strength = value->value;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return strength;
|
||||
}
|
||||
|
||||
const char *
|
||||
get_strength_nick (GtkConstraintStrength strength)
|
||||
{
|
||||
GEnumClass *class = g_type_class_ref (GTK_TYPE_CONSTRAINT_STRENGTH);
|
||||
GEnumValue *value = g_enum_get_value (class, strength);
|
||||
const char *nick = value->value_nick;
|
||||
g_type_class_unref (class);
|
||||
|
||||
return nick;
|
||||
}
|
||||
|
||||
void
|
||||
guide_editor_serialize_guide (GString *str,
|
||||
int indent,
|
||||
GtkConstraintGuide *guide)
|
||||
{
|
||||
int min_width, min_height;
|
||||
int nat_width, nat_height;
|
||||
int max_width, max_height;
|
||||
const char *name;
|
||||
const char *strength;
|
||||
|
||||
gtk_constraint_guide_get_min_size (guide, &min_width, &min_height);
|
||||
gtk_constraint_guide_get_nat_size (guide, &nat_width, &nat_height);
|
||||
gtk_constraint_guide_get_max_size (guide, &max_width, &max_height);
|
||||
name = gtk_constraint_guide_get_name (guide);
|
||||
strength = get_strength_nick (gtk_constraint_guide_get_strength (guide));
|
||||
|
||||
g_string_append_printf (str, "%*s<guide min-width=\"%d\" min-height=\"%d\"\n", indent, "", min_width, min_height);
|
||||
g_string_append_printf (str, "%*s nat-width=\"%d\" nat-height=\"%d\"\n", indent, "", nat_width, nat_height);
|
||||
g_string_append_printf (str, "%*s max-width=\"%d\" max-height=\"%d\"\n", indent, "", max_width, max_height);
|
||||
g_string_append_printf (str, "%*s name=\"%s\" strength=\"%s\" />\n", indent, "", name, strength);
|
||||
}
|
||||
|
||||
static void
|
||||
create_guide (GtkButton *button,
|
||||
GuideEditor *editor)
|
||||
{
|
||||
const char *id;
|
||||
int strength;
|
||||
const char *name;
|
||||
int w, h;
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
if (editor->guide)
|
||||
guide = g_object_ref (editor->guide);
|
||||
else
|
||||
guide = gtk_constraint_guide_new ();
|
||||
|
||||
name = gtk_editable_get_text (GTK_EDITABLE (editor->name));
|
||||
gtk_constraint_guide_set_name (guide, name);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->min_height));
|
||||
gtk_constraint_guide_set_min_size (guide, w, h);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->nat_height));
|
||||
gtk_constraint_guide_set_nat_size (guide, w, h);
|
||||
|
||||
w = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_width));
|
||||
h = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (editor->max_height));
|
||||
gtk_constraint_guide_set_max_size (guide, w, h);
|
||||
|
||||
id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (editor->strength));
|
||||
strength = get_strength (id);
|
||||
gtk_constraint_guide_set_strength (guide, strength);
|
||||
|
||||
g_signal_emit (editor, signals[DONE], 0, guide);
|
||||
g_object_unref (guide);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_init (GuideEditor *editor)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (editor));
|
||||
}
|
||||
|
||||
static int guide_counter;
|
||||
|
||||
static int
|
||||
min_input (GtkSpinButton *spin_button,
|
||||
double *new_val)
|
||||
{
|
||||
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||
{
|
||||
*new_val = 0.0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
max_input (GtkSpinButton *spin_button,
|
||||
double *new_val)
|
||||
{
|
||||
if (strcmp (gtk_editable_get_text (GTK_EDITABLE (spin_button)), "") == 0)
|
||||
{
|
||||
*new_val = G_MAXINT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
min_output (GtkSpinButton *spin_button)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
double value;
|
||||
GtkWidget *box, *text;
|
||||
|
||||
adjustment = gtk_spin_button_get_adjustment (spin_button);
|
||||
value = gtk_adjustment_get_value (adjustment);
|
||||
|
||||
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
|
||||
text = gtk_widget_get_first_child (box);
|
||||
|
||||
if (value == 0.0)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
max_output (GtkSpinButton *spin_button)
|
||||
{
|
||||
GtkAdjustment *adjustment;
|
||||
double value;
|
||||
GtkWidget *box, *text;
|
||||
|
||||
adjustment = gtk_spin_button_get_adjustment (spin_button);
|
||||
value = gtk_adjustment_get_value (adjustment);
|
||||
|
||||
box = gtk_widget_get_first_child (GTK_WIDGET (spin_button));
|
||||
text = gtk_widget_get_first_child (box);
|
||||
|
||||
if (value == (double)G_MAXINT)
|
||||
{
|
||||
gtk_editable_set_text (GTK_EDITABLE (spin_button), "");
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "unset");
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_set_placeholder_text (GTK_TEXT (text), "");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_constructed (GObject *object)
|
||||
{
|
||||
GuideEditor *editor = GUIDE_EDITOR (object);
|
||||
|
||||
guide_strength_combo (editor->strength);
|
||||
|
||||
g_signal_connect (editor->min_width, "input", G_CALLBACK (min_input), NULL);
|
||||
g_signal_connect (editor->min_width, "output", G_CALLBACK (min_output), NULL);
|
||||
|
||||
g_signal_connect (editor->min_height, "input", G_CALLBACK (min_input), NULL);
|
||||
g_signal_connect (editor->min_height, "output", G_CALLBACK (min_output), NULL);
|
||||
|
||||
g_signal_connect (editor->max_width, "input", G_CALLBACK (max_input), NULL);
|
||||
g_signal_connect (editor->max_width, "output", G_CALLBACK (max_output), NULL);
|
||||
|
||||
g_signal_connect (editor->max_height, "input", G_CALLBACK (max_input), NULL);
|
||||
g_signal_connect (editor->max_height, "output", G_CALLBACK (max_output), NULL);
|
||||
|
||||
if (editor->guide)
|
||||
{
|
||||
GtkConstraintStrength strength;
|
||||
const char *nick;
|
||||
int w, h;
|
||||
|
||||
nick = gtk_constraint_guide_get_name (editor->guide);
|
||||
if (nick)
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->name), nick);
|
||||
|
||||
gtk_constraint_guide_get_min_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), h);
|
||||
|
||||
gtk_constraint_guide_get_nat_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), h);
|
||||
|
||||
gtk_constraint_guide_get_max_size (editor->guide, &w, &h);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), w);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), h);
|
||||
|
||||
strength = gtk_constraint_guide_get_strength (editor->guide);
|
||||
nick = get_strength_nick (strength);
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), nick);
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Apply");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *name;
|
||||
|
||||
guide_counter++;
|
||||
name = g_strdup_printf ("Guide %d", guide_counter);
|
||||
gtk_editable_set_text (GTK_EDITABLE (editor->name), name);
|
||||
g_free (name);
|
||||
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_width), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->min_height), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_width), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->nat_height), 0.0);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_width), G_MAXINT);
|
||||
gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->max_height), G_MAXINT);
|
||||
|
||||
gtk_combo_box_set_active_id (GTK_COMBO_BOX (editor->strength), "medium");
|
||||
|
||||
gtk_button_set_label (GTK_BUTTON (editor->button), "Create");
|
||||
}
|
||||
|
||||
editor->constructed = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GuideEditor *self = GUIDE_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GUIDE:
|
||||
self->guide = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GuideEditor *self = GUIDE_EDITOR (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GUIDE:
|
||||
g_value_set_object (value, self->guide);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_dispose (GObject *object)
|
||||
{
|
||||
GuideEditor *self = (GuideEditor *)object;
|
||||
|
||||
g_clear_pointer (&self->grid, gtk_widget_unparent);
|
||||
g_clear_object (&self->guide);
|
||||
|
||||
G_OBJECT_CLASS (guide_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
guide_editor_class_init (GuideEditorClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||
|
||||
object_class->constructed = guide_editor_constructed;
|
||||
object_class->dispose = guide_editor_dispose;
|
||||
object_class->set_property = guide_editor_set_property;
|
||||
object_class->get_property = guide_editor_get_property;
|
||||
|
||||
pspecs[PROP_GUIDE] =
|
||||
g_param_spec_object ("guide", "guide", "guide",
|
||||
GTK_TYPE_CONSTRAINT_GUIDE,
|
||||
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, pspecs);
|
||||
|
||||
signals[DONE] =
|
||||
g_signal_new ("done",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1, GTK_TYPE_CONSTRAINT_GUIDE);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class,
|
||||
"/org/gtk/gtk4/constraint-editor/guide-editor.ui");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, grid);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, name);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, min_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, nat_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_width);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, max_height);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, strength);
|
||||
gtk_widget_class_bind_template_child (widget_class, GuideEditor, button);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, create_guide);
|
||||
}
|
||||
|
||||
GuideEditor *
|
||||
guide_editor_new (GtkConstraintGuide *guide)
|
||||
{
|
||||
return g_object_new (GUIDE_EDITOR_TYPE,
|
||||
"guide", guide,
|
||||
NULL);
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#define GUIDE_EDITOR_TYPE (guide_editor_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GuideEditor, guide_editor, GUIDE, EDITOR, GtkWidget)
|
||||
|
||||
GuideEditor * guide_editor_new (GtkConstraintGuide *guide);
|
||||
|
||||
void guide_editor_serialize_guide (GString *str,
|
||||
int indent,
|
||||
GtkConstraintGuide *guide);
|
@@ -1,188 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="min_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="min_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="nat_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="nat_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="max_width_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="max_height_adj">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">2147483647</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">10</property>
|
||||
<property name="page-size">0</property>
|
||||
</object>
|
||||
<template class="GuideEditor" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<property name="margin">20</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Name</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="name">
|
||||
<property name="max-width-chars">20</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Min Size</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="min_width">
|
||||
<property name="adjustment">min_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="min_height">
|
||||
<property name="adjustment">min_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Nat Size</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="nat_width">
|
||||
<property name="adjustment">nat_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="nat_height">
|
||||
<property name="adjustment">nat_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Max Size</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="max_width">
|
||||
<property name="adjustment">max_width_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSpinButton" id="max_height">
|
||||
<property name="adjustment">max_height_adj</property>
|
||||
<property name="max-width-chars">5</property>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Strength</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="strength">
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
<property name="column-span">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="button">
|
||||
<property name="label">Create</property>
|
||||
<signal name="clicked" handler="create_guide"/>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
<property name="top-attach">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 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/>.
|
||||
*
|
||||
* Authors: Matthias Clasen <mclasen@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <constraint-editor-application.h>
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
return g_application_run (G_APPLICATION (constraint_editor_application_new ()), argc, argv);
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
constraint_editor_sources = [
|
||||
'main.c',
|
||||
'constraint-editor-application.c',
|
||||
'constraint-editor-window.c',
|
||||
'constraint-view.c',
|
||||
'constraint-editor.c',
|
||||
'guide-editor.c',
|
||||
]
|
||||
|
||||
constraint_editor_resources = gnome.compile_resources('constraint_editor_resources',
|
||||
'constraint-editor.gresource.xml',
|
||||
source_dir: '.')
|
||||
|
||||
executable('gtk4-constraint-editor',
|
||||
constraint_editor_sources, constraint_editor_resources,
|
||||
dependencies: libgtk_dep,
|
||||
include_directories: confinc,
|
||||
gui_app: true,
|
||||
link_args: extra_demo_ldflags,
|
||||
install: false)
|
@@ -212,7 +212,7 @@ activate_about (GSimpleAction *action,
|
||||
"comments", "Program to demonstrate GTK functions.",
|
||||
"authors", authors,
|
||||
"documenters", documentors,
|
||||
"logo-icon-name", "org.gtk.Demo4",
|
||||
"logo-icon-name", "org.gtk.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");
|
||||
@@ -419,7 +419,7 @@ demo_application_window_load_state (DemoApplicationWindow *win)
|
||||
static void
|
||||
demo_application_window_init (DemoApplicationWindow *window)
|
||||
{
|
||||
GtkWidget *popover;
|
||||
GtkWidget *menu;
|
||||
|
||||
window->width = -1;
|
||||
window->height = -1;
|
||||
@@ -428,8 +428,8 @@ demo_application_window_init (DemoApplicationWindow *window)
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (window));
|
||||
|
||||
popover = gtk_popover_menu_new_from_model (window->menutool, window->toolmenu);
|
||||
gtk_menu_tool_button_set_popover (GTK_MENU_TOOL_BUTTON (window->menutool), popover);
|
||||
menu = gtk_menu_new_from_model (window->toolmenu);
|
||||
gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (window->menutool), menu);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (window),
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
@@ -477,7 +477,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 +487,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 +541,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,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="DemoApplicationWindow" parent="GtkApplicationWindow">
|
||||
<property name="title" translatable="yes">Application Class</property>
|
||||
@@ -33,34 +32,42 @@
|
||||
<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">
|
||||
<property name="visible">0</property>
|
||||
<property name="hexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="hexpand">1</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox" id="content_area">
|
||||
<child>
|
||||
<object class="GtkLabel" id="message">
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">_OK</property>
|
||||
<property name="use-underline">1</property>
|
||||
<signal name="clicked" handler="clicked_cb"/>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="valign">center</property>
|
||||
<property name="label" translatable="yes">_OK</property>
|
||||
<property name="use-underline">1</property>
|
||||
<signal name="clicked" handler="clicked_cb"/>
|
||||
</object>
|
||||
</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">
|
||||
@@ -72,20 +79,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,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="appmenu">
|
||||
<section>
|
||||
|
@@ -94,7 +94,6 @@ create_page1 (GtkWidget *assistant)
|
||||
GtkWidget *box, *label, *entry;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
g_object_set (box, "margin", 12, NULL);
|
||||
|
||||
label = gtk_label_new ("You must fill out this entry to continue:");
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
@@ -116,12 +115,10 @@ create_page2 (GtkWidget *assistant)
|
||||
{
|
||||
GtkWidget *box, *checkbutton;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
|
||||
g_object_set (box, "margin", 12, NULL);
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
|
||||
checkbutton = gtk_check_button_new_with_label ("This is optional data, you may continue "
|
||||
"even if you do not check this");
|
||||
gtk_widget_set_valign (checkbutton, GTK_ALIGN_CENTER);
|
||||
gtk_container_add (GTK_CONTAINER (box), checkbutton);
|
||||
|
||||
gtk_assistant_append_page (GTK_ASSISTANT (assistant), box);
|
||||
|
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkWindow" id="window">
|
||||
@@ -17,11 +16,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 +28,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">
|
||||
@@ -67,53 +66,53 @@
|
||||
<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>
|
||||
<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>
|
||||
<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="GtkImage">
|
||||
<style>
|
||||
<class name="duck"/>
|
||||
</style>
|
||||
<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="GtkImage">
|
||||
<style>
|
||||
<class name="gradient"/>
|
||||
</style>
|
||||
<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">
|
||||
<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>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
@@ -121,12 +120,12 @@ Blended picture</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>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
@@ -146,53 +145,53 @@ Blended picture</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>
|
||||
<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>
|
||||
<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="GtkImage">
|
||||
<style>
|
||||
<class name="red"/>
|
||||
</style>
|
||||
<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="GtkImage">
|
||||
<style>
|
||||
<class name="blue"/>
|
||||
</style>
|
||||
<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">
|
||||
<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>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">2</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
@@ -200,12 +199,12 @@ Blended picture</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>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="width">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
@@ -228,33 +227,33 @@ Blended picture</property>
|
||||
<style>
|
||||
<class name="cyan"/>
|
||||
</style>
|
||||
<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="GtkImage">
|
||||
<style>
|
||||
<class name="magenta"/>
|
||||
</style>
|
||||
<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="GtkImage">
|
||||
<style>
|
||||
<class name="yellow"/>
|
||||
</style>
|
||||
<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>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
@@ -262,11 +261,11 @@ Blended picture</property>
|
||||
<style>
|
||||
<class name="blend2"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
@@ -275,11 +274,11 @@ Blended picture</property>
|
||||
<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="GtkLabel">
|
||||
@@ -288,11 +287,11 @@ Blended picture</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<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">
|
||||
@@ -301,11 +300,11 @@ Blended picture</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<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="GtkLabel">
|
||||
@@ -314,21 +313,21 @@ Blended picture</property>
|
||||
<attributes>
|
||||
<attribute name="weight" value="bold"></attribute>
|
||||
</attributes>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</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>
|
||||
|
@@ -458,6 +458,7 @@ blur_overlay_class_init (BlurOverlayClass *klass)
|
||||
static void
|
||||
blur_overlay_init (BlurOverlay *overlay)
|
||||
{
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (overlay), FALSE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
@@ -38,22 +38,7 @@ help_activate (GSimpleAction *action,
|
||||
g_print ("Help not available\n");
|
||||
}
|
||||
|
||||
static void
|
||||
not_implemented (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_print ("Action “%s” not implemented\n", g_action_get_name (G_ACTION (action)));
|
||||
}
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "new", not_implemented, NULL, NULL, NULL },
|
||||
{ "open", not_implemented, NULL, NULL, NULL },
|
||||
{ "save", not_implemented, NULL, NULL, NULL },
|
||||
{ "save-as", not_implemented, NULL, NULL, NULL },
|
||||
{ "copy", not_implemented, NULL, NULL, NULL },
|
||||
{ "cut", not_implemented, NULL, NULL, NULL },
|
||||
{ "paste", not_implemented, NULL, NULL, NULL },
|
||||
{ "quit", quit_activate, NULL, NULL, NULL },
|
||||
{ "about", about_activate, NULL, NULL, NULL },
|
||||
{ "help", help_activate, NULL, NULL, NULL }
|
||||
@@ -65,6 +50,8 @@ do_builder (GtkWidget *do_widget)
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *toolbar;
|
||||
GActionGroup *actions;
|
||||
GtkAccelGroup *accel_group;
|
||||
GtkWidget *item;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
@@ -72,6 +59,7 @@ do_builder (GtkWidget *do_widget)
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/builder/demo.ui");
|
||||
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
@@ -85,6 +73,44 @@ do_builder (GtkWidget *do_widget)
|
||||
win_entries, G_N_ELEMENTS (win_entries),
|
||||
window);
|
||||
gtk_widget_insert_action_group (window, "win", actions);
|
||||
accel_group = gtk_accel_group_new ();
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "new_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_n, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "open_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "save_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_s, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "quit_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "copy_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "cut_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_x, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "paste_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_v, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "help_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_F1, 0, GTK_ACCEL_VISIBLE);
|
||||
|
||||
item = (GtkWidget*)gtk_builder_get_object (builder, "about_item");
|
||||
gtk_widget_add_accelerator (item, "activate", accel_group,
|
||||
GDK_KEY_F7, 0, GTK_ACCEL_VISIBLE);
|
||||
|
||||
g_object_set_data_full (G_OBJECT(window), "builder", builder, g_object_unref);
|
||||
}
|
||||
|
552
demos/gtk-demo/changedisplay.c
Normal file
552
demos/gtk-demo/changedisplay.c
Normal file
@@ -0,0 +1,552 @@
|
||||
/* Change Display
|
||||
*
|
||||
* Demonstrates migrating a window between different displays.
|
||||
* A display is a mouse and keyboard with some number of
|
||||
* associated monitors. The neat thing about having multiple
|
||||
* displays is that they can be on a completely separate
|
||||
* 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
|
||||
* 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
|
||||
* a single display.
|
||||
*
|
||||
* This is a moderately complex example, and demonstrates:
|
||||
*
|
||||
* - Tracking the currently open displays
|
||||
*
|
||||
* - Changing the display for a window
|
||||
*
|
||||
* - Letting the user choose a window by clicking on it
|
||||
*
|
||||
* - Using GtkListStore and GtkTreeView
|
||||
*
|
||||
* - Using GtkDialog
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/* The ChangeDisplayInfo structure corresponds to a toplevel window and
|
||||
* holds pointers to widgets inside the toplevel window along with other
|
||||
* information about the contents of the window.
|
||||
* This is a common organizational structure in real applications.
|
||||
*/
|
||||
typedef struct _ChangeDisplayInfo ChangeDisplayInfo;
|
||||
|
||||
struct _ChangeDisplayInfo
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkSizeGroup *size_group;
|
||||
|
||||
GtkTreeModel *display_model;
|
||||
|
||||
GdkDisplay *current_display;
|
||||
};
|
||||
|
||||
/* These enumerations provide symbolic names for the columns
|
||||
* in the two GtkListStore models.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
DISPLAY_COLUMN_NAME,
|
||||
DISPLAY_COLUMN_DISPLAY,
|
||||
DISPLAY_NUM_COLUMNS
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SCREEN_COLUMN_NUMBER,
|
||||
SCREEN_COLUMN_SCREEN,
|
||||
SCREEN_NUM_COLUMNS
|
||||
};
|
||||
|
||||
/* Finds the toplevel window under the mouse pointer, if any.
|
||||
*/
|
||||
static GtkWidget *
|
||||
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);
|
||||
|
||||
if (pointer_window)
|
||||
widget = GTK_WIDGET (gtk_root_get_for_surface (pointer_window));
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
static void
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gboolean *clicked)
|
||||
{
|
||||
*clicked = TRUE;
|
||||
}
|
||||
|
||||
/* Asks the user to click on a window, then waits for them click
|
||||
* the mouse. When the mouse is released, returns the toplevel
|
||||
* window under the pointer, or NULL, if there is none.
|
||||
*/
|
||||
static GtkWidget *
|
||||
query_for_toplevel (GdkDisplay *display,
|
||||
const char *prompt)
|
||||
{
|
||||
GtkWidget *popup, *label, *frame;
|
||||
GdkCursor *cursor;
|
||||
GtkWidget *toplevel = NULL;
|
||||
GdkDevice *device;
|
||||
|
||||
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);
|
||||
gtk_container_add (GTK_CONTAINER (popup), frame);
|
||||
|
||||
label = gtk_label_new (prompt);
|
||||
g_object_set (label, "margin", 10, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
|
||||
gtk_widget_show (popup);
|
||||
cursor = gdk_cursor_new_from_name ("crosshair", NULL);
|
||||
device = gtk_get_current_event_device ();
|
||||
|
||||
if (gdk_seat_grab (gdk_device_get_seat (device),
|
||||
gtk_widget_get_surface (popup),
|
||||
GDK_SEAT_CAPABILITY_ALL_POINTING,
|
||||
FALSE, cursor, NULL, NULL, NULL) == GDK_GRAB_SUCCESS)
|
||||
{
|
||||
GtkGesture *gesture = gtk_gesture_multi_press_new ();
|
||||
gboolean clicked = FALSE;
|
||||
|
||||
g_signal_connect (gesture, "released",
|
||||
G_CALLBACK (released_cb), &clicked);
|
||||
gtk_widget_add_controller (popup, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
/* 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
|
||||
* are no events currently.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
g_object_unref (cursor);
|
||||
gtk_widget_destroy (popup);
|
||||
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
/* Prompts the user for a toplevel window to move, and then moves
|
||||
* that window to the currently selected display
|
||||
*/
|
||||
static void
|
||||
query_change_display (ChangeDisplayInfo *info)
|
||||
{
|
||||
GdkDisplay *display = gtk_widget_get_display (info->window);
|
||||
GtkWidget *toplevel;
|
||||
|
||||
toplevel = query_for_toplevel (display,
|
||||
"Please select the toplevel\n"
|
||||
"to move to the new display");
|
||||
|
||||
if (toplevel)
|
||||
gtk_window_set_display (GTK_WINDOW (toplevel), info->current_display);
|
||||
else
|
||||
gdk_display_beep (display);
|
||||
}
|
||||
|
||||
/* Called when the user clicks on a button in our dialog or
|
||||
* closes the dialog through the window manager. Unless the
|
||||
* "Change" button was clicked, we destroy the dialog.
|
||||
*/
|
||||
static void
|
||||
response_cb (GtkDialog *dialog,
|
||||
gint response_id,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_OK)
|
||||
query_change_display (info);
|
||||
else
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
}
|
||||
|
||||
/* Called when the user clicks on "Open..." in the display
|
||||
* frame. Prompts for a new display, and then opens a connection
|
||||
* to that display.
|
||||
*/
|
||||
static void
|
||||
open_display_cb (GtkWidget *button,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *display_entry;
|
||||
GtkWidget *dialog_label;
|
||||
gchar *new_screen_name = NULL;
|
||||
GdkDisplay *result = NULL;
|
||||
|
||||
dialog = gtk_dialog_new_with_buttons ("Open Display",
|
||||
GTK_WINDOW (info->window),
|
||||
GTK_DIALOG_MODAL,
|
||||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||||
_("_OK"), GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||
display_entry = gtk_entry_new ();
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (display_entry), TRUE);
|
||||
dialog_label =
|
||||
gtk_label_new ("Please enter the name of\nthe new display\n");
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (content_area), dialog_label);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), display_entry);
|
||||
|
||||
gtk_widget_grab_focus (display_entry);
|
||||
|
||||
while (!result)
|
||||
{
|
||||
gint response_id = gtk_dialog_run (GTK_DIALOG (dialog));
|
||||
if (response_id != GTK_RESPONSE_OK)
|
||||
break;
|
||||
|
||||
new_screen_name = gtk_editable_get_chars (GTK_EDITABLE (display_entry),
|
||||
0, -1);
|
||||
|
||||
if (strcmp (new_screen_name, "") != 0)
|
||||
{
|
||||
result = gdk_display_open (new_screen_name);
|
||||
if (!result)
|
||||
{
|
||||
gchar *error_msg =
|
||||
g_strdup_printf ("Can't open display:\n\t%s\nplease try another one\n",
|
||||
new_screen_name);
|
||||
gtk_label_set_text (GTK_LABEL (dialog_label), error_msg);
|
||||
g_free (error_msg);
|
||||
}
|
||||
|
||||
g_free (new_screen_name);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
/* Called when the user clicks on the "Close" button in the
|
||||
* "Display" frame. Closes the selected display.
|
||||
*/
|
||||
static void
|
||||
close_display_cb (GtkWidget *button,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
if (info->current_display)
|
||||
gdk_display_close (info->current_display);
|
||||
}
|
||||
|
||||
/* Called when the selected row in the display list changes.
|
||||
* Updates info->current_display, then refills the list of
|
||||
* screens.
|
||||
*/
|
||||
static void
|
||||
display_changed_cb (GtkTreeSelection *selection,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
|
||||
if (info->current_display)
|
||||
g_object_unref (info->current_display);
|
||||
if (gtk_tree_selection_get_selected (selection, &model, &iter))
|
||||
gtk_tree_model_get (model, &iter,
|
||||
DISPLAY_COLUMN_DISPLAY, &info->current_display,
|
||||
-1);
|
||||
else
|
||||
info->current_display = NULL;
|
||||
}
|
||||
|
||||
/* This function is used both for creating the "Display" and
|
||||
* "Screen" frames, since they have a similar structure. The
|
||||
* caller hooks up the right context for the value returned
|
||||
* in tree_view, and packs any relevant buttons into button_vbox.
|
||||
*/
|
||||
static void
|
||||
create_frame (ChangeDisplayInfo *info,
|
||||
const char *title,
|
||||
GtkWidget **frame,
|
||||
GtkWidget **tree_view,
|
||||
GtkWidget **button_vbox)
|
||||
{
|
||||
GtkTreeSelection *selection;
|
||||
GtkWidget *scrollwin;
|
||||
GtkWidget *hbox;
|
||||
|
||||
*frame = gtk_frame_new (title);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
g_object_set (hbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (*frame), hbox);
|
||||
|
||||
scrollwin = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
|
||||
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);
|
||||
|
||||
*tree_view = gtk_tree_view_new ();
|
||||
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (*tree_view), FALSE);
|
||||
gtk_container_add (GTK_CONTAINER (scrollwin), *tree_view);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (*tree_view));
|
||||
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);
|
||||
|
||||
if (!info->size_group)
|
||||
info->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
|
||||
gtk_size_group_add_widget (GTK_SIZE_GROUP (info->size_group), *button_vbox);
|
||||
}
|
||||
|
||||
/* If we have a stack of buttons, it often looks better if their contents
|
||||
* are left-aligned, rather than centered. This function creates a button
|
||||
* and left-aligns it contents.
|
||||
*/
|
||||
GtkWidget *
|
||||
left_align_button_new (const char *label)
|
||||
{
|
||||
GtkWidget *button = gtk_button_new_with_mnemonic (label);
|
||||
GtkWidget *child = gtk_bin_get_child (GTK_BIN (button));
|
||||
|
||||
gtk_widget_set_halign (child, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (child, GTK_ALIGN_CENTER);
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
/* Creates the "Display" frame in the main window.
|
||||
*/
|
||||
GtkWidget *
|
||||
create_display_frame (ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *tree_view;
|
||||
GtkWidget *button_vbox;
|
||||
GtkTreeViewColumn *column;
|
||||
GtkTreeSelection *selection;
|
||||
GtkWidget *button;
|
||||
|
||||
create_frame (info, "Display", &frame, &tree_view, &button_vbox);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
info->display_model = (GtkTreeModel *)gtk_list_store_new (DISPLAY_NUM_COLUMNS,
|
||||
G_TYPE_STRING,
|
||||
GDK_TYPE_DISPLAY);
|
||||
|
||||
gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), info->display_model);
|
||||
|
||||
column = gtk_tree_view_column_new_with_attributes ("Name",
|
||||
gtk_cell_renderer_text_new (),
|
||||
"text", DISPLAY_COLUMN_NAME,
|
||||
NULL);
|
||||
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
|
||||
|
||||
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
|
||||
g_signal_connect (selection, "changed",
|
||||
G_CALLBACK (display_changed_cb), info);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/* Called when one of the currently open displays is closed.
|
||||
* Remove it from our list of displays.
|
||||
*/
|
||||
static void
|
||||
display_closed_cb (GdkDisplay *display,
|
||||
gboolean is_error,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
gboolean valid;
|
||||
|
||||
for (valid = gtk_tree_model_get_iter_first (info->display_model, &iter);
|
||||
valid;
|
||||
valid = gtk_tree_model_iter_next (info->display_model, &iter))
|
||||
{
|
||||
GdkDisplay *tmp_display;
|
||||
|
||||
gtk_tree_model_get (info->display_model, &iter,
|
||||
DISPLAY_COLUMN_DISPLAY, &tmp_display,
|
||||
-1);
|
||||
if (tmp_display == display)
|
||||
{
|
||||
gtk_list_store_remove (GTK_LIST_STORE (info->display_model), &iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds a new display to our list of displays, and connects
|
||||
* to the "closed" signal so that we can remove it from the
|
||||
* list of displays again.
|
||||
*/
|
||||
static void
|
||||
add_display (ChangeDisplayInfo *info,
|
||||
GdkDisplay *display)
|
||||
{
|
||||
const gchar *name = gdk_display_get_name (display);
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_list_store_append (GTK_LIST_STORE (info->display_model), &iter);
|
||||
gtk_list_store_set (GTK_LIST_STORE (info->display_model), &iter,
|
||||
DISPLAY_COLUMN_NAME, name,
|
||||
DISPLAY_COLUMN_DISPLAY, display,
|
||||
-1);
|
||||
|
||||
g_signal_connect (display, "closed",
|
||||
G_CALLBACK (display_closed_cb), info);
|
||||
}
|
||||
|
||||
/* Called when a new display is opened
|
||||
*/
|
||||
static void
|
||||
display_opened_cb (GdkDisplayManager *manager,
|
||||
GdkDisplay *display,
|
||||
ChangeDisplayInfo *info)
|
||||
{
|
||||
add_display (info, display);
|
||||
}
|
||||
|
||||
/* Adds all currently open displays to our list of displays,
|
||||
* and set up a signal connection so that we'll be notified
|
||||
* when displays are opened in the future as well.
|
||||
*/
|
||||
static void
|
||||
initialize_displays (ChangeDisplayInfo *info)
|
||||
{
|
||||
GdkDisplayManager *manager = gdk_display_manager_get ();
|
||||
GSList *displays = gdk_display_manager_list_displays (manager);
|
||||
GSList *tmp_list;
|
||||
|
||||
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
|
||||
add_display (info, tmp_list->data);
|
||||
|
||||
g_slist_free (tmp_list);
|
||||
|
||||
g_signal_connect (manager, "display-opened",
|
||||
G_CALLBACK (display_opened_cb), info);
|
||||
}
|
||||
|
||||
/* Cleans up when the toplevel is destroyed; we remove the
|
||||
* connections we use to track currently open displays, then
|
||||
* free the ChangeDisplayInfo structure.
|
||||
*/
|
||||
static void
|
||||
destroy_info (ChangeDisplayInfo *info)
|
||||
{
|
||||
GdkDisplayManager *manager = gdk_display_manager_get ();
|
||||
GSList *displays = gdk_display_manager_list_displays (manager);
|
||||
GSList *tmp_list;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (manager,
|
||||
display_opened_cb,
|
||||
info);
|
||||
|
||||
for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
|
||||
g_signal_handlers_disconnect_by_func (tmp_list->data,
|
||||
display_closed_cb,
|
||||
info);
|
||||
|
||||
g_slist_free (tmp_list);
|
||||
|
||||
g_object_unref (info->size_group);
|
||||
g_object_unref (info->display_model);
|
||||
|
||||
if (info->current_display)
|
||||
g_object_unref (info->current_display);
|
||||
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_cb (GObject *object,
|
||||
ChangeDisplayInfo **info)
|
||||
{
|
||||
destroy_info (*info);
|
||||
*info = NULL;
|
||||
}
|
||||
|
||||
/* Main entry point. If the dialog for this demo doesn't yet exist, creates
|
||||
* it. Otherwise, destroys it.
|
||||
*/
|
||||
GtkWidget *
|
||||
do_changedisplay (GtkWidget *do_widget)
|
||||
{
|
||||
static ChangeDisplayInfo *info = NULL;
|
||||
|
||||
if (!info)
|
||||
{
|
||||
GtkWidget *content_area;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *frame;
|
||||
|
||||
info = g_new0 (ChangeDisplayInfo, 1);
|
||||
|
||||
info->window = gtk_dialog_new_with_buttons ("Change Display",
|
||||
GTK_WINDOW (do_widget),
|
||||
0,
|
||||
"Close", GTK_RESPONSE_CLOSE,
|
||||
"Change", GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (info->window), 300, 400);
|
||||
|
||||
g_signal_connect (info->window, "response",
|
||||
G_CALLBACK (response_cb), info);
|
||||
g_signal_connect (info->window, "destroy",
|
||||
G_CALLBACK (destroy_cb), &info);
|
||||
|
||||
content_area = gtk_dialog_get_content_area (GTK_DIALOG (info->window));
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
|
||||
g_object_set (vbox, "margin", 8, NULL);
|
||||
gtk_container_add (GTK_CONTAINER (content_area), vbox);
|
||||
|
||||
frame = create_display_frame (info);
|
||||
gtk_container_add (GTK_CONTAINER (vbox), frame);
|
||||
|
||||
initialize_displays (info);
|
||||
|
||||
gtk_widget_show (info->window);
|
||||
return info->window;
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_widget_destroy (info->window);
|
||||
return NULL;
|
||||
}
|
||||
}
|
@@ -110,7 +110,7 @@ get_image_paintable (GtkImage *image)
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon_name, 48, GTK_ICON_LOOKUP_GENERIC_FALLBACK);
|
||||
if (icon_info == NULL)
|
||||
return NULL;
|
||||
return gtk_icon_info_load_icon (icon_info, NULL);
|
||||
return GDK_PAINTABLE (gtk_icon_info_load_texture (icon_info));
|
||||
default:
|
||||
g_warning ("Image storage type %d not handled",
|
||||
gtk_image_get_storage_type (image));
|
||||
@@ -119,85 +119,59 @@ get_image_paintable (GtkImage *image)
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
GtkWidget *widget)
|
||||
drag_begin (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (paintable)
|
||||
{
|
||||
gtk_drag_source_set_icon (source, paintable, -2, -2);
|
||||
gtk_drag_set_icon_paintable (drag, paintable, -2, -2);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_texture (GValue *value,
|
||||
gpointer data)
|
||||
void
|
||||
drag_data_get (GtkWidget *widget,
|
||||
GdkDrag *drag,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
gpointer data)
|
||||
{
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
GdkPaintable *paintable;
|
||||
|
||||
paintable = get_image_paintable (GTK_IMAGE (widget));
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
g_value_set_object (value, paintable);
|
||||
}
|
||||
|
||||
static GdkContentProvider *
|
||||
prepare_drag (GtkDragSource *source,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *image)
|
||||
{
|
||||
return gdk_content_provider_new_with_callback (GDK_TYPE_TEXTURE, get_texture, image);
|
||||
gtk_selection_data_set_texture (selection_data, GDK_TEXTURE (paintable));
|
||||
}
|
||||
|
||||
static void
|
||||
got_texture (GObject *source,
|
||||
GAsyncResult *result,
|
||||
gpointer data)
|
||||
drag_data_received (GtkWidget *widget,
|
||||
GdkDrop *drop,
|
||||
GtkSelectionData *selection_data,
|
||||
gpointer data)
|
||||
{
|
||||
GdkDrop *drop = GDK_DROP (source);
|
||||
GtkWidget *image = data;
|
||||
const GValue *value;
|
||||
GError *error = NULL;
|
||||
|
||||
value = gdk_drop_read_value_finish (drop, result, &error);
|
||||
if (value)
|
||||
if (gtk_selection_data_get_length (selection_data) > 0)
|
||||
{
|
||||
GdkTexture *texture = g_value_get_object (value);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (image), GDK_PAINTABLE (texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_print ("Failed to get data: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
GdkTexture *texture;
|
||||
|
||||
static gboolean
|
||||
drag_drop (GtkDropTarget *dest,
|
||||
GdkDrop *drop,
|
||||
int x,
|
||||
int y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
if (gdk_drop_has_value (drop, GDK_TYPE_TEXTURE))
|
||||
{
|
||||
gdk_drop_read_value_async (drop, GDK_TYPE_TEXTURE, G_PRIORITY_DEFAULT, NULL, got_texture, widget);
|
||||
return TRUE;
|
||||
texture = gtk_selection_data_get_texture (selection_data);
|
||||
gtk_image_set_from_paintable (GTK_IMAGE (data), GDK_PAINTABLE (texture));
|
||||
g_object_unref (texture);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_image (GSimpleAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
copy_image (GtkMenuItem *item,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
GdkPaintable *paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
GdkClipboard *clipboard;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
paintable = get_image_paintable (GTK_IMAGE (data));
|
||||
|
||||
if (GDK_IS_TEXTURE (paintable))
|
||||
gdk_clipboard_set_texture (clipboard, GDK_TEXTURE (paintable));
|
||||
@@ -222,12 +196,16 @@ paste_image_received (GObject *source,
|
||||
}
|
||||
|
||||
static void
|
||||
paste_image (GSimpleAction *action,
|
||||
GVariant *value,
|
||||
gpointer data)
|
||||
paste_image (GtkMenuItem *item,
|
||||
gpointer data)
|
||||
{
|
||||
GdkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
gdk_clipboard_read_texture_async (clipboard, NULL, paste_image_received, data);
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (data));
|
||||
gdk_clipboard_read_texture_async (clipboard,
|
||||
NULL,
|
||||
paste_image_received,
|
||||
data);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -237,23 +215,22 @@ pressed_cb (GtkGesture *gesture,
|
||||
double y,
|
||||
GtkWidget *image)
|
||||
{
|
||||
GtkWidget *popover;
|
||||
GMenu *menu;
|
||||
GMenuItem *item;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *item;
|
||||
|
||||
menu = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_append_item (menu, item);
|
||||
menu = gtk_menu_new ();
|
||||
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_append_item (menu, item);
|
||||
item = gtk_menu_item_new_with_mnemonic (_("_Copy"));
|
||||
g_signal_connect (item, "activate", G_CALLBACK (copy_image), image);
|
||||
gtk_widget_show (item);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
|
||||
popover = gtk_popover_menu_new_from_model (image, G_MENU_MODEL (menu));
|
||||
item = gtk_menu_item_new_with_mnemonic (_("_Paste"));
|
||||
g_signal_connect (item, "activate", G_CALLBACK (paste_image), image);
|
||||
gtk_widget_show (item);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (popover), &(GdkRectangle) { x, y, 1, 1});
|
||||
gtk_popover_popup (GTK_POPOVER (popover));
|
||||
|
||||
g_object_unref (menu);
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
@@ -266,14 +243,6 @@ do_clipboard (GtkWidget *do_widget)
|
||||
GtkWidget *entry, *button;
|
||||
GtkWidget *image;
|
||||
GtkGesture *gesture;
|
||||
GActionEntry entries[] = {
|
||||
{ "copy", copy_image, NULL, NULL, NULL },
|
||||
{ "paste", paste_image, NULL, NULL, NULL },
|
||||
};
|
||||
GActionGroup *actions;
|
||||
GtkDragSource *source;
|
||||
GtkDropTarget *dest;
|
||||
GdkContentFormats *formats;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
@@ -332,65 +301,53 @@ do_clipboard (GtkWidget *do_widget)
|
||||
|
||||
/* Create the first image */
|
||||
image = gtk_image_new_from_icon_name ("dialog-warning");
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
|
||||
/* make image a drag source */
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_source_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-begin",
|
||||
G_CALLBACK (drag_begin), image);
|
||||
g_signal_connect (image, "drag-data-get",
|
||||
G_CALLBACK (drag_data_get), image);
|
||||
|
||||
/* accept drops on image */
|
||||
formats = gdk_content_formats_new_for_gtype (GDK_TYPE_TEXTURE);
|
||||
dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
|
||||
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
|
||||
NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_dest_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-data-received",
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gesture = gtk_gesture_multi_press_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
|
||||
|
||||
gtk_widget_insert_action_group (image, "clipboard", actions);
|
||||
|
||||
g_object_unref (actions);
|
||||
|
||||
/* Create the second image */
|
||||
image = gtk_image_new_from_icon_name ("process-stop");
|
||||
gtk_image_set_pixel_size (GTK_IMAGE (image), 48);
|
||||
gtk_container_add (GTK_CONTAINER (hbox), image);
|
||||
|
||||
/* make image a drag source */
|
||||
source = gtk_drag_source_new ();
|
||||
g_signal_connect (source, "prepare", G_CALLBACK (prepare_drag), NULL);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (source));
|
||||
gtk_drag_source_set (image, GDK_BUTTON1_MASK, NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_source_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-begin",
|
||||
G_CALLBACK (drag_begin), image);
|
||||
g_signal_connect (image, "drag-data-get",
|
||||
G_CALLBACK (drag_data_get), image);
|
||||
|
||||
/* accept drops on image */
|
||||
formats = gdk_content_formats_new_for_gtype (GDK_TYPE_TEXTURE);
|
||||
dest = gtk_drop_target_new (formats, GDK_ACTION_COPY);
|
||||
gdk_content_formats_unref (formats);
|
||||
g_signal_connect (dest, "drag-drop", G_CALLBACK (drag_drop), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (dest));
|
||||
gtk_drag_dest_set (image, GTK_DEST_DEFAULT_ALL,
|
||||
NULL, GDK_ACTION_COPY);
|
||||
gtk_drag_dest_add_image_targets (image);
|
||||
g_signal_connect (image, "drag-data-received",
|
||||
G_CALLBACK (drag_data_received), image);
|
||||
|
||||
/* context menu on image */
|
||||
gesture = gtk_gesture_click_new ();
|
||||
gesture = gtk_gesture_multi_press_new ();
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (pressed_cb), image);
|
||||
gtk_widget_add_controller (image, GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), image);
|
||||
|
||||
gtk_widget_insert_action_group (image, "clipboard", actions);
|
||||
|
||||
g_object_unref (actions);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -1,289 +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 || Space || Child 2 | |
|
||||
* | +-----------++-------++-----------+ |
|
||||
* | +---------------------------------+ |
|
||||
* | | Child 3 | |
|
||||
* | +---------------------------------+ |
|
||||
* +-------------------------------------+
|
||||
*
|
||||
* Constraints:
|
||||
*
|
||||
* super.start = child1.start - 8
|
||||
* child1.width = child2.width
|
||||
* child1.end = space.start
|
||||
* space.end = child2.start
|
||||
* 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
|
||||
*
|
||||
* To add some flexibility, we make the space
|
||||
* stretchable:
|
||||
*
|
||||
* space.width >= 10
|
||||
* space.width = 100
|
||||
* space.width <= 200
|
||||
*/
|
||||
static void
|
||||
build_constraints (SimpleGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
guide = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (guide, "space");
|
||||
gtk_constraint_guide_set_min_size (guide, 10, 10);
|
||||
gtk_constraint_guide_set_nat_size (guide, 100, 10);
|
||||
gtk_constraint_guide_set_max_size (guide, 200, 20);
|
||||
gtk_constraint_guide_set_strength (guide, GTK_CONSTRAINT_STRENGTH_STRONG);
|
||||
gtk_constraint_layout_add_guide (manager, guide);
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_RELATION_LE,
|
||||
200.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
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,
|
||||
guide,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (guide,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.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,245 +0,0 @@
|
||||
/* Constraints/Interactive
|
||||
*
|
||||
* Demonstrate how constraints can be updates during
|
||||
* user interaction.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget)
|
||||
|
||||
struct _InteractiveGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *button1, *button2;
|
||||
GtkWidget *button3;
|
||||
GtkConstraintGuide *guide;
|
||||
GtkConstraint *constraint;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
interactive_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
InteractiveGrid *self = INTERACTIVE_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 (interactive_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
interactive_grid_class_init (InteractiveGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = interactive_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
build_constraints (InteractiveGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
|
||||
gtk_constraint_layout_add_guide (manager, self->guide);
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (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,
|
||||
GTK_CONSTRAINT_TARGET (self->button3),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button2),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (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
|
||||
drag_cb (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
InteractiveGrid *self)
|
||||
{
|
||||
GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self)));
|
||||
double x, y;
|
||||
|
||||
if (self->constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (layout, self->constraint);
|
||||
g_clear_object (&self->constraint);
|
||||
}
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
||||
self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
x + offset_x,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint));
|
||||
gtk_widget_queue_allocate (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
interactive_grid_init (InteractiveGrid *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkGesture *drag;
|
||||
|
||||
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));
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag));
|
||||
}
|
||||
|
||||
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 (interactive_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,165 +0,0 @@
|
||||
/* Constraints/VFL
|
||||
*
|
||||
* GtkConstraintLayout allows defining constraints using a
|
||||
* compact syntax called Visual Format Language, or VFL.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (VflGrid, vfl_grid, VFL, GRID, GtkWidget)
|
||||
|
||||
struct _VflGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *button1, *button2;
|
||||
GtkWidget *button3;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (VflGrid, vfl_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
vfl_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
VflGrid *self = VFL_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 (vfl_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
vfl_grid_class_init (VflGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = vfl_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
|
||||
*
|
||||
* Visual format:
|
||||
*
|
||||
* H:|-8-[view1(==view2)-12-[view2]-8-|
|
||||
* H:|-8-[view3]-8-|
|
||||
* V:|-8-[view1]-12-[view3(==view1)]-8-|
|
||||
* V:|-8-[view2]-12-[view3(==view2)]-8-|
|
||||
*/
|
||||
static void
|
||||
build_constraints (VflGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
const char * const vfl[] = {
|
||||
"H:|-[button1(==button2)]-12-[button2]-|",
|
||||
"H:|-[button3]-|",
|
||||
"V:|-[button1]-12-[button3(==button1)]-|",
|
||||
"V:|-[button2]-12-[button3(==button2)]-|",
|
||||
};
|
||||
GError *error = NULL;
|
||||
|
||||
gtk_constraint_layout_add_constraints_from_description (manager, vfl, G_N_ELEMENTS (vfl),
|
||||
8, 8,
|
||||
&error,
|
||||
"button1", self->button1,
|
||||
"button2", self->button2,
|
||||
"button3", self->button3,
|
||||
NULL);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_printerr ("VFL parsing error:\n%s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vfl_grid_init (VflGrid *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_constraints3 (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 (vfl_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;
|
||||
}
|
@@ -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";
|
||||
|
@@ -24,6 +24,7 @@ do_cursors (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/cursors/cursors.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GdkCursor" id="default_cursor">
|
||||
<property name="name">default</property>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -10,7 +10,7 @@
|
||||
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"
|
||||
sodipodi:docname="org.gtk.Demo-symbolic.svg"
|
||||
height="16.03125"
|
||||
id="svg7384"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
@@ -37,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>
|
||||
@@ -104,9 +101,6 @@
|
||||
<file>gtkfishbowl.c</file>
|
||||
<file>gtkfishbowl.h</file>
|
||||
</gresource>
|
||||
<gresource prefix="/iconscroll">
|
||||
<file>iconscroll.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/iconview">
|
||||
<file>gnome-fs-directory.png</file>
|
||||
<file>gnome-fs-regular.png</file>
|
||||
@@ -149,12 +143,10 @@
|
||||
<file>application_demo.c</file>
|
||||
<file>assistant.c</file>
|
||||
<file>builder.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>
|
||||
@@ -166,22 +158,19 @@
|
||||
<file>drawingarea.c</file>
|
||||
<file>dnd.c</file>
|
||||
<file>editable_cells.c</file>
|
||||
<file>entry_buffer.c</file>
|
||||
<file>entry_completion.c</file>
|
||||
<file>entry_undo.c</file>
|
||||
<file>expander.c</file>
|
||||
<file>filtermodel.c</file>
|
||||
<file>fishbowl.c</file>
|
||||
<file>fixed.c</file>
|
||||
<file>flowbox.c</file>
|
||||
<file>foreigndrawing.c</file>
|
||||
<file>font_features.c</file>
|
||||
<file>fontplane.c</file>
|
||||
<file>fontrendering.c</file>
|
||||
<file>gestures.c</file>
|
||||
<file>glarea.c</file>
|
||||
<file>headerbar.c</file>
|
||||
<file>hypertext.c</file>
|
||||
<file>iconscroll.c</file>
|
||||
<file>iconview.c</file>
|
||||
<file>iconview_edit.c</file>
|
||||
<file>images.c</file>
|
||||
@@ -190,6 +179,7 @@
|
||||
<file>listbox.c</file>
|
||||
<file>list_store.c</file>
|
||||
<file>markup.c</file>
|
||||
<file>menus.c</file>
|
||||
<file>modelbutton.c</file>
|
||||
<file>overlay.c</file>
|
||||
<file>overlay2.c</file>
|
||||
@@ -218,11 +208,9 @@
|
||||
<file>spinner.c</file>
|
||||
<file>tabs.c</file>
|
||||
<file>tagged_entry.c</file>
|
||||
<file>textundo.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>
|
||||
@@ -282,13 +270,7 @@
|
||||
<file>demotaggedentry.c</file>
|
||||
<file>demotaggedentry.h</file>
|
||||
</gresource>
|
||||
<gresource prefix="/fixed">
|
||||
<file>fixed.css</file>
|
||||
</gresource>
|
||||
<gresource prefix="/fontrendering">
|
||||
<file>fontrendering.ui</file>
|
||||
</gresource>
|
||||
<gresource prefix="/org/gtk/Demo4">
|
||||
<gresource prefix="/org/gtk/Demo">
|
||||
<file>icons/16x16/actions/application-exit.png</file>
|
||||
<file>icons/16x16/actions/document-new.png</file>
|
||||
<file>icons/16x16/actions/document-open.png</file>
|
||||
|
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
<columns>
|
||||
@@ -22,75 +21,6 @@
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<menu id="menubar">
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_File</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_New</attribute>
|
||||
<attribute name="action">win.new</attribute>
|
||||
<attribute name="accel"><Primary>n</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Open</attribute>
|
||||
<attribute name="action">win.open</attribute>
|
||||
<attribute name="accel"><Primary>o</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Save</attribute>
|
||||
<attribute name="action">win.save</attribute>
|
||||
<attribute name="accel"><Primary>s</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Save _As</attribute>
|
||||
<attribute name="action">win.save-as</attribute>
|
||||
<attribute name="accel"><Primary>q</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Quit</attribute>
|
||||
<attribute name="action">win.quit</attribute>
|
||||
<attribute name="accel"><Primary><Shift>s</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Edit</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Copy</attribute>
|
||||
<attribute name="action">win.copy</attribute>
|
||||
<attribute name="accel"><Primary>c</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Cut</attribute>
|
||||
<attribute name="action">win.cut</attribute>
|
||||
<attribute name="accel"><Primary>x</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Paste</attribute>
|
||||
<attribute name="action">win.paste</attribute>
|
||||
<attribute name="accel"><Primary>v</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
<submenu>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Help</attribute>
|
||||
<attribute name="action">win.help</attribute>
|
||||
<attribute name="accel">F1</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About</attribute>
|
||||
<attribute name="action">win.about</attribute>
|
||||
<attribute name="accel">F7</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</submenu>
|
||||
</menu>
|
||||
<object class="GtkAboutDialog" id="aboutdialog1">
|
||||
<property name="program-name" translatable="yes">Builder demo</property>
|
||||
<property name="logo-icon-name" translatable="yes">gtk3-demo</property>
|
||||
@@ -106,8 +36,109 @@
|
||||
<object class="GtkBox" id="vbox1">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkPopoverMenuBar" id="menubar1">
|
||||
<property name="menu-model">menubar</property>
|
||||
<object class="GtkMenuBar" id="menubar1">
|
||||
<child internal-child="accessible">
|
||||
<object class="AtkObject" id="a11y-menubar">
|
||||
<property name="AtkObject::accessible-name">The menubar</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="label" translatable="yes">_File</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="new_item">
|
||||
<property name="label" translatable="yes">_New</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="open_item">
|
||||
<property name="label" translatable="yes">_Open</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="save_item">
|
||||
<property name="label" translatable="yes">_Save</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="save_as_item">
|
||||
<property name="label" translatable="yes">Save _As</property>
|
||||
<property name="use-underline">1</property>
|
||||
<accelerator key="s" modifiers="primary | shift-mask" signal="activate"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="quit_item">
|
||||
<property name="label" translatable="yes">_Quit</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.quit</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="label" translatable="yes">_Edit</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="copy_item">
|
||||
<property name="label" translatable="yes">_Copy</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="cut_item">
|
||||
<property name="label" translatable="yes">_Cut</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="paste_item">
|
||||
<property name="label" translatable="yes">_Paste</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem">
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use-underline">1</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="help_item">
|
||||
<property name="label" translatable="yes">_Help</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.help</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="about_item">
|
||||
<property name="label" translatable="yes">_About</property>
|
||||
<property name="use-underline">1</property>
|
||||
<property name="action-name">win.about</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@@ -41,6 +41,8 @@ demo_tagged_entry_init (DemoTaggedEntry *entry)
|
||||
{
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (entry), FALSE);
|
||||
|
||||
priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_widget_set_parent (priv->box, GTK_WIDGET (entry));
|
||||
|
||||
@@ -129,13 +131,13 @@ demo_tagged_entry_size_allocate (GtkWidget *widget,
|
||||
baseline);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
demo_tagged_entry_grab_focus (GtkWidget *widget)
|
||||
{
|
||||
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
|
||||
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
|
||||
|
||||
return gtk_widget_grab_focus (priv->entry);
|
||||
gtk_widget_grab_focus (priv->entry);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -250,11 +252,11 @@ static guint signals[LAST_SIGNAL] = { 0, };
|
||||
G_DEFINE_TYPE (DemoTaggedEntryTag, demo_tagged_entry_tag, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
on_released (GtkGestureClick *gesture,
|
||||
on_released (GtkGestureMultiPress *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
DemoTaggedEntryTag *tag)
|
||||
DemoTaggedEntryTag *tag)
|
||||
{
|
||||
g_signal_emit (tag, signals[SIGNAL_CLICKED], 0);
|
||||
}
|
||||
@@ -265,12 +267,14 @@ demo_tagged_entry_tag_init (DemoTaggedEntryTag *tag)
|
||||
GtkGesture *gesture;
|
||||
GtkCssProvider *provider;
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (tag), FALSE);
|
||||
|
||||
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 ();
|
||||
gesture = gtk_gesture_multi_press_new ();
|
||||
g_signal_connect (gesture, "released", G_CALLBACK (on_released), tag);
|
||||
gtk_widget_add_controller (GTK_WIDGET (tag), GTK_EVENT_CONTROLLER (gesture));
|
||||
|
||||
|
@@ -1,8 +1,6 @@
|
||||
/* Drag-and-Drop
|
||||
*
|
||||
* I can't believe its not glade!
|
||||
*
|
||||
* Try right-clicking in the window.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
@@ -94,7 +92,7 @@ deserialize_widget (GtkDemoWidget *demo)
|
||||
static double pos_x, pos_y;
|
||||
|
||||
static void
|
||||
new_label_cb (GtkWidget *button,
|
||||
new_label_cb (GtkMenuItem *item,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFixed *fixed = data;
|
||||
@@ -102,12 +100,10 @@ new_label_cb (GtkWidget *button,
|
||||
|
||||
widget = gtk_label_new ("Label");
|
||||
gtk_fixed_put (fixed, widget, pos_x, pos_y);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
new_spinner_cb (GtkWidget *button,
|
||||
new_spinner_cb (GtkMenuItem *item,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFixed *fixed = data;
|
||||
@@ -117,39 +113,33 @@ new_spinner_cb (GtkWidget *button,
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (widget), "demo");
|
||||
gtk_spinner_start (GTK_SPINNER (widget));
|
||||
gtk_fixed_put (fixed, widget, pos_x, pos_y);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
copy_cb (GtkWidget *button, GtkWidget *child)
|
||||
copy_cb (GtkWidget *child)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
GtkDemoWidget *demo;
|
||||
|
||||
g_print ("Copy %s\n", G_OBJECT_TYPE_NAME (child));
|
||||
|
||||
demo = serialize_widget (child);
|
||||
|
||||
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||
gdk_clipboard_set (clipboard, GTK_TYPE_DEMO_WIDGET, demo);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
delete_cb (GtkWidget *button, GtkWidget *child)
|
||||
delete_cb (GtkWidget *child)
|
||||
{
|
||||
gtk_widget_destroy (child);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
cut_cb (GtkWidget *button, GtkWidget *child)
|
||||
cut_cb (GtkWidget *child)
|
||||
{
|
||||
copy_cb (button, child);
|
||||
delete_cb (button, child);
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
copy_cb (child);
|
||||
delete_cb (child);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -185,7 +175,7 @@ value_read (GObject *source,
|
||||
}
|
||||
|
||||
static void
|
||||
paste_cb (GtkWidget *button, GtkWidget *fixed)
|
||||
paste_cb (GtkWidget *fixed)
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
@@ -197,8 +187,6 @@ paste_cb (GtkWidget *button, GtkWidget *fixed)
|
||||
}
|
||||
else
|
||||
g_print ("Don't know how to handle clipboard contents\n");
|
||||
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -217,7 +205,7 @@ edit_label_done (GtkWidget *entry, gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
edit_cb (GtkWidget *button, GtkWidget *child)
|
||||
edit_cb (GtkWidget *child)
|
||||
{
|
||||
GtkWidget *fixed = gtk_widget_get_parent (child);
|
||||
int x, y;
|
||||
@@ -231,7 +219,6 @@ edit_cb (GtkWidget *button, 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_editable_set_width_chars (GTK_EDITABLE (entry), 12);
|
||||
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,9 +230,6 @@ edit_cb (GtkWidget *button, GtkWidget *child)
|
||||
g_object_get (child, "active", &active, NULL);
|
||||
g_object_set (child, "active", !active, NULL);
|
||||
}
|
||||
|
||||
if (button)
|
||||
gtk_popover_popdown (GTK_POPOVER (gtk_widget_get_ancestor (button, GTK_TYPE_POPOVER)));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -259,69 +243,69 @@ 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)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *box;
|
||||
GtkWidget *item;
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
pos_x = x;
|
||||
pos_y = y;
|
||||
|
||||
menu = gtk_popover_new (widget);
|
||||
gtk_popover_set_has_arrow (GTK_POPOVER (menu), FALSE);
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (menu), &(GdkRectangle){ x, y, 1, 1});
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (menu), box);
|
||||
menu = gtk_menu_new ();
|
||||
item = gtk_menu_item_new_with_label ("New Label");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (new_label_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("New Spinner");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (new_spinner_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
|
||||
item = gtk_button_new_with_label ("New Label");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (new_label_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("New Spinner");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (new_spinner_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_separator_menu_item_new ();
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
|
||||
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
|
||||
item = gtk_button_new_with_label ("Edit");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
item = gtk_menu_item_new_with_label ("Edit");
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (edit_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (edit_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
|
||||
item = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_separator_menu_item_new ();
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
|
||||
item = gtk_button_new_with_label ("Cut");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
item = gtk_menu_item_new_with_label ("Cut");
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (cut_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("Copy");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (cut_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("Copy");
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (copy_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("Paste");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (copy_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("Paste");
|
||||
clipboard = gdk_display_get_clipboard (gdk_display_get_default ());
|
||||
gtk_widget_set_sensitive (item,
|
||||
gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), GTK_TYPE_DEMO_WIDGET));
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (paste_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
item = gtk_button_new_with_label ("Delete");
|
||||
gtk_button_set_relief (GTK_BUTTON (item), GTK_RELIEF_NONE);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (paste_cb), widget);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
item = gtk_menu_item_new_with_label ("Delete");
|
||||
gtk_widget_set_sensitive (item, child != NULL && child != widget);
|
||||
g_signal_connect (item, "clicked", G_CALLBACK (delete_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (box), item);
|
||||
g_signal_connect_swapped (item, "activate", G_CALLBACK (delete_cb), child);
|
||||
gtk_container_add (GTK_CONTAINER (menu), item);
|
||||
|
||||
gtk_popover_popup (GTK_POPOVER (menu));
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
rect.width = 0;
|
||||
rect.height = 0;
|
||||
|
||||
gtk_menu_popup_at_rect (GTK_MENU (menu),
|
||||
gtk_widget_get_surface (widget),
|
||||
&rect,
|
||||
GDK_GRAVITY_NORTH_WEST,
|
||||
GDK_GRAVITY_NORTH_WEST,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,12 +320,12 @@ 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)
|
||||
{
|
||||
if (child != NULL && child != widget)
|
||||
edit_cb (NULL, child);
|
||||
edit_cb (child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +356,7 @@ do_dnd (GtkWidget *do_widget)
|
||||
gtk_widget_set_hexpand (fixed, TRUE);
|
||||
gtk_widget_set_vexpand (fixed, TRUE);
|
||||
|
||||
multipress = gtk_gesture_click_new ();
|
||||
multipress = gtk_gesture_multi_press_new ();
|
||||
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);
|
||||
|
@@ -1,29 +1,28 @@
|
||||
/* Entry/Entry Undo
|
||||
/* Entry/Entry Buffer
|
||||
*
|
||||
* GtkEntry can provide basic Undo/Redo support using standard keyboard
|
||||
* accelerators such as Primary+z to undo and Primary+Shift+z to redo.
|
||||
* Additionally, Primary+y can be used to redo.
|
||||
*
|
||||
* Use gtk_entry_set_enable_undo() to enable undo/redo support.
|
||||
* GtkEntryBuffer provides the text content in a GtkEntry.
|
||||
* Applications can provide their own buffer implementation,
|
||||
* e.g. to provide secure handling for passwords in memory.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
GtkWidget *
|
||||
do_entry_undo (GtkWidget *do_widget)
|
||||
do_entry_buffer (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window = NULL;
|
||||
GtkWidget *vbox;
|
||||
GtkWidget *label;
|
||||
GtkWidget *entry;
|
||||
GtkEntryBuffer *buffer;
|
||||
|
||||
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), "Entry Undo");
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Entry Buffer");
|
||||
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
@@ -34,13 +33,22 @@ do_entry_undo (GtkWidget *do_widget)
|
||||
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label),
|
||||
"Use Primary+z or Primary+Shift+z to undo or redo changes");
|
||||
"Entries share a buffer. Typing in one is reflected in the other.");
|
||||
gtk_container_add (GTK_CONTAINER (vbox), label);
|
||||
|
||||
/* Create our entry */
|
||||
entry = gtk_entry_new ();
|
||||
gtk_editable_set_enable_undo (GTK_EDITABLE (entry), TRUE);
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
g_object_unref (buffer);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (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_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));
|
||||
|
@@ -122,6 +122,7 @@ do_filtermodel (GtkWidget *do_widget)
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/filtermodel/filtermodel.ui");
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<object class="GtkListStore" id="liststore1">
|
||||
@@ -45,11 +44,11 @@
|
||||
<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 +83,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,11 +134,11 @@
|
||||
<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">
|
||||
@@ -151,11 +150,11 @@
|
||||
<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">
|
||||
@@ -167,11 +166,11 @@
|
||||
<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 +199,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>
|
||||
|
@@ -124,7 +124,7 @@ 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_wrap (GTK_LABEL (w), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (w), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (w), 100);
|
||||
|
||||
return w;
|
||||
@@ -164,26 +164,6 @@ create_switch (void)
|
||||
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);
|
||||
@@ -199,7 +179,6 @@ static const struct {
|
||||
{ "Video", create_video },
|
||||
{ "Gears", create_gears },
|
||||
{ "Switch", create_switch },
|
||||
{ "Menubutton", create_menu_button },
|
||||
};
|
||||
|
||||
static int selected_widget_type = -1;
|
||||
@@ -219,15 +198,15 @@ set_widget_type (GtkFishbowl *fishbowl,
|
||||
gtk_fishbowl_set_creation_func (fishbowl,
|
||||
widget_types[selected_widget_type].create_func);
|
||||
|
||||
window = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (fishbowl)));
|
||||
window = gtk_widget_get_toplevel (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);
|
||||
}
|
||||
|
||||
void
|
||||
fishbowl_next_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
next_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFishbowl *fishbowl = user_data;
|
||||
int new_index;
|
||||
@@ -241,8 +220,8 @@ fishbowl_next_button_clicked_cb (GtkButton *source,
|
||||
}
|
||||
|
||||
void
|
||||
fishbowl_prev_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
prev_button_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFishbowl *fishbowl = user_data;
|
||||
int new_index;
|
||||
@@ -255,15 +234,6 @@ fishbowl_prev_button_clicked_cb (GtkButton *source,
|
||||
set_widget_type (fishbowl, new_index);
|
||||
}
|
||||
|
||||
void
|
||||
fishbowl_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");
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_fishbowl (GtkWidget *do_widget)
|
||||
@@ -288,6 +258,11 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
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),
|
||||
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);
|
||||
@@ -300,7 +275,6 @@ do_fishbowl (GtkWidget *do_widget)
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
gtk_widget_realize (window);
|
||||
g_object_unref (builder);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
|
@@ -1,9 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<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>
|
||||
@@ -15,13 +12,13 @@
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-start-symbolic</property>
|
||||
<signal name="clicked" handler="fishbowl_prev_button_clicked_cb" object="bowl" swapped="no"/>
|
||||
<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="fishbowl_next_button_clicked_cb" object="bowl" swapped="no"/>
|
||||
<signal name="clicked" handler="next_button_clicked_cb" object="bowl" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -30,28 +27,42 @@
|
||||
<object class="GtkLabel">
|
||||
<property name="label">fps</property>
|
||||
</object>
|
||||
<packing/>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" bind-source="bowl" bind-property="framerate-string"/>
|
||||
<property name="label" bind-source="bowl" bind-property="framerate"/>
|
||||
</object>
|
||||
<packing/>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Icons, </property>
|
||||
</object>
|
||||
<packing/>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkLabel">
|
||||
<property name="label" bind-source="bowl" bind-property="count"/>
|
||||
</object>
|
||||
<packing/>
|
||||
</child>
|
||||
<child type="end">
|
||||
<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="fishbowl_changes_toggled_cb"/>
|
||||
</object>
|
||||
<packing/>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkToggleButton" id="changes_prevent">
|
||||
<property name="active" bind-source="changes_allow" bind-property="active" bind-flags="bidirectional|invert-boolean"/>
|
||||
<property name="visible" bind-source="changes_prevent" bind-property="active" bind-flags="invert-boolean"/>
|
||||
<property name="icon-name">changes-prevent</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
<packing/>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
@@ -59,7 +70,7 @@
|
||||
<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"/>
|
||||
<property name="benchmark" bind-source="changes_allow" bind-property="active" bind-flags="invert-boolean"/>
|
||||
</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,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.12"/>
|
||||
<object class="GtkWindow" id="window">
|
||||
@@ -13,7 +12,7 @@
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="tooltip-text">Reset</property>
|
||||
<signal name="clicked" handler="font_features_reset_features" swapped="no"/>
|
||||
<signal name="clicked" handler="reset" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">view-refresh-symbolic</property>
|
||||
@@ -42,7 +41,7 @@
|
||||
<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_features_font_changed" swapped="no"/>
|
||||
<signal name="font-set" handler="font_changed" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -63,7 +62,7 @@
|
||||
<object class="GtkComboBox" id="script_lang">
|
||||
<property name="can-focus">1</property>
|
||||
<property name="margin-top">10</property>
|
||||
<signal name="changed" handler="font_features_script_changed" swapped="no"/>
|
||||
<signal name="changed" handler="script_changed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkCellRendererText"/>
|
||||
<attributes>
|
||||
@@ -137,7 +136,7 @@
|
||||
Разъяренный чтец эгоистично бьёт пятью жердями шустрого фехтовальщика. Наш банк вчера же выплатил Ф.Я. Эйхгольду комиссию за ценные вещи. Эх, чужак, общий съём цен шляп (юфть) – вдрызг! В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!
|
||||
|
||||
Τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός</property>
|
||||
<signal name="activate" handler="font_features_stop_edit"/>
|
||||
<signal name="activate" handler="stop_edit"/>
|
||||
<property name="valign">start</property>
|
||||
<property name="width-chars">50</property>
|
||||
</object>
|
||||
@@ -181,7 +180,7 @@
|
||||
<property name="icon-name">document-edit-symbolic</property>
|
||||
<property name="halign">end</property>
|
||||
<property name="valign">end</property>
|
||||
<signal name="toggled" handler="font_features_toggle_edit"/>
|
||||
<signal name="toggled" handler="toggle_edit"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,8 @@
|
||||
|
||||
#include "fontplane.h"
|
||||
|
||||
#include "gtk.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_WEIGHT_ADJUSTMENT,
|
||||
@@ -207,6 +209,7 @@ 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 ();
|
||||
|
@@ -1,287 +0,0 @@
|
||||
/* Pango/Font rendering
|
||||
*
|
||||
* Demonstrates various aspects of font rendering.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *font_button = NULL;
|
||||
static GtkWidget *entry = NULL;
|
||||
static GtkWidget *image = NULL;
|
||||
static GtkWidget *hinting = NULL;
|
||||
static GtkWidget *hint_metrics = NULL;
|
||||
static GtkWidget *up_button = NULL;
|
||||
static GtkWidget *down_button = NULL;
|
||||
static GtkWidget *text_radio = NULL;
|
||||
static GtkWidget *show_grid = NULL;
|
||||
static GtkWidget *show_extents = NULL;
|
||||
|
||||
static PangoContext *context;
|
||||
|
||||
static int scale = 10;
|
||||
|
||||
static void
|
||||
on_destroy (gpointer data)
|
||||
{
|
||||
window = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
update_image (void)
|
||||
{
|
||||
const char *text;
|
||||
PangoFontDescription *desc;
|
||||
PangoLayout *layout;
|
||||
PangoRectangle ink, pink, logical;
|
||||
int baseline;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkPixbuf *pixbuf2;
|
||||
const char *hint;
|
||||
cairo_font_options_t *fopt;
|
||||
cairo_hint_style_t hintstyle;
|
||||
cairo_hint_metrics_t hintmetrics;
|
||||
int i;
|
||||
|
||||
if (!context)
|
||||
context = gtk_widget_create_pango_context (image);
|
||||
|
||||
text = gtk_editable_get_text (GTK_EDITABLE (entry));
|
||||
desc = gtk_font_chooser_get_font_desc (GTK_FONT_CHOOSER (font_button));
|
||||
|
||||
fopt = cairo_font_options_copy (pango_cairo_context_get_font_options (context));
|
||||
|
||||
hint = gtk_combo_box_get_active_id (GTK_COMBO_BOX (hinting));
|
||||
if (strcmp (hint, "none") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_NONE;
|
||||
else if (strcmp (hint, "slight") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_SLIGHT;
|
||||
else if (strcmp (hint, "medium") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_MEDIUM;
|
||||
else if (strcmp (hint, "full") == 0)
|
||||
hintstyle = CAIRO_HINT_STYLE_FULL;
|
||||
else
|
||||
hintstyle = CAIRO_HINT_STYLE_DEFAULT;
|
||||
cairo_font_options_set_hint_style (fopt, hintstyle);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (hint_metrics)))
|
||||
hintmetrics = CAIRO_HINT_METRICS_ON;
|
||||
else
|
||||
hintmetrics = CAIRO_HINT_METRICS_OFF;
|
||||
cairo_font_options_set_hint_metrics (fopt, hintmetrics);
|
||||
|
||||
pango_cairo_context_set_font_options (context, fopt);
|
||||
cairo_font_options_destroy (fopt);
|
||||
pango_context_changed (context);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (text_radio)))
|
||||
{
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, text, -1);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
pink = ink;
|
||||
baseline = pango_layout_get_baseline (layout);
|
||||
|
||||
pango_extents_to_pixels (&ink, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, ink.width + 20, ink.height + 20);
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
cairo_move_to (cr, 10, 10);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
|
||||
cairo_destroy (cr);
|
||||
g_object_unref (layout);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
|
||||
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
|
||||
|
||||
g_object_unref (pixbuf);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (pixbuf2),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
gdk_pixbuf_get_width (pixbuf2),
|
||||
gdk_pixbuf_get_height (pixbuf2),
|
||||
gdk_pixbuf_get_rowstride (pixbuf2));
|
||||
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_line_width (cr, 1);
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_grid)))
|
||||
{
|
||||
cairo_set_source_rgba (cr, 0.2, 0, 0, 0.2);
|
||||
for (i = 1; i < ink.height + 20; i++)
|
||||
{
|
||||
cairo_move_to (cr, 0, scale * i - 0.5);
|
||||
cairo_line_to (cr, scale * (ink.width + 20), scale * i - 0.5);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
for (i = 1; i < ink.width + 20; i++)
|
||||
{
|
||||
cairo_move_to (cr, scale * i - 0.5, 0);
|
||||
cairo_line_to (cr, scale * i - 0.5, scale * (ink.height + 20));
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
}
|
||||
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (show_extents)))
|
||||
{
|
||||
cairo_set_source_rgba (cr, 0, 0, 1, 1);
|
||||
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (logical.y)) - 0.5,
|
||||
scale * pango_units_to_double (logical.width) + 1,
|
||||
scale * pango_units_to_double (logical.height) + 1);
|
||||
cairo_stroke (cr);
|
||||
cairo_move_to (cr, scale * (10 + pango_units_to_double (logical.x)) - 0.5,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_line_to (cr, scale * (10 + pango_units_to_double (logical.x + logical.width)) + 1,
|
||||
scale * (10 + pango_units_to_double (baseline)) - 0.5);
|
||||
cairo_stroke (cr);
|
||||
cairo_set_source_rgba (cr, 1, 0, 0, 1);
|
||||
cairo_rectangle (cr,
|
||||
scale * (10 + pango_units_to_double (pink.x)) + 0.5,
|
||||
scale * (10 + pango_units_to_double (pink.y)) + 0.5,
|
||||
scale * pango_units_to_double (pink.width) - 1,
|
||||
scale * pango_units_to_double (pink.height) - 1);
|
||||
cairo_stroke (cr);
|
||||
}
|
||||
|
||||
cairo_surface_destroy (surface);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
else
|
||||
{
|
||||
PangoLayoutIter *iter;
|
||||
PangoLayoutRun *run;
|
||||
PangoGlyphInfo *g;
|
||||
int i, j;
|
||||
|
||||
layout = pango_layout_new (context);
|
||||
pango_layout_set_font_description (layout, desc);
|
||||
pango_layout_set_text (layout, "aaaa", -1);
|
||||
pango_layout_get_extents (layout, &ink, &logical);
|
||||
pango_extents_to_pixels (&logical, NULL);
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, logical.width * 3 / 2, 4*logical.height);
|
||||
cr = cairo_create (surface);
|
||||
cairo_set_source_rgb (cr, 1, 1, 1);
|
||||
cairo_paint (cr);
|
||||
|
||||
iter = pango_layout_get_iter (layout);
|
||||
run = pango_layout_iter_get_run (iter);
|
||||
|
||||
cairo_set_source_rgb (cr, 0, 0, 0);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[i]);
|
||||
g->geometry.width = PANGO_UNITS_ROUND (g->geometry.width * 3 / 2);
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
g = &(run->glyphs->glyphs[i]);
|
||||
g->geometry.x_offset = i * (PANGO_SCALE / 4);
|
||||
g->geometry.y_offset = j * (PANGO_SCALE / 4);
|
||||
}
|
||||
|
||||
cairo_move_to (cr, 0, j * logical.height);
|
||||
pango_cairo_show_layout (cr, layout);
|
||||
}
|
||||
|
||||
cairo_destroy (cr);
|
||||
pango_layout_iter_free (iter);
|
||||
g_object_unref (layout);
|
||||
|
||||
pixbuf = gdk_pixbuf_get_from_surface (surface, 0, 0, cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface));
|
||||
pixbuf2 = gdk_pixbuf_scale_simple (pixbuf, gdk_pixbuf_get_width (pixbuf) * scale, gdk_pixbuf_get_height (pixbuf) * scale, GDK_INTERP_NEAREST);
|
||||
g_object_unref (pixbuf);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
|
||||
gtk_picture_set_pixbuf (GTK_PICTURE (image), pixbuf2);
|
||||
|
||||
g_object_unref (pixbuf2);
|
||||
|
||||
pango_font_description_free (desc);
|
||||
}
|
||||
|
||||
static void
|
||||
update_buttons (void)
|
||||
{
|
||||
gtk_widget_set_sensitive (up_button, scale < 32);
|
||||
gtk_widget_set_sensitive (down_button, scale > 1);
|
||||
}
|
||||
|
||||
static void
|
||||
scale_up (void)
|
||||
{
|
||||
scale += 1;
|
||||
update_buttons ();
|
||||
update_image ();
|
||||
}
|
||||
|
||||
static void
|
||||
scale_down (void)
|
||||
{
|
||||
scale -= 1;
|
||||
update_buttons ();
|
||||
update_image ();
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_fontrendering (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/fontrendering/fontrendering.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (on_destroy), NULL);
|
||||
g_object_set_data_full (G_OBJECT (window), "builder", builder, g_object_unref);
|
||||
font_button = GTK_WIDGET (gtk_builder_get_object (builder, "font_button"));
|
||||
up_button = GTK_WIDGET (gtk_builder_get_object (builder, "up_button"));
|
||||
down_button = GTK_WIDGET (gtk_builder_get_object (builder, "down_button"));
|
||||
entry = GTK_WIDGET (gtk_builder_get_object (builder, "entry"));
|
||||
image = GTK_WIDGET (gtk_builder_get_object (builder, "image"));
|
||||
hinting = GTK_WIDGET (gtk_builder_get_object (builder, "hinting"));
|
||||
hint_metrics = GTK_WIDGET (gtk_builder_get_object (builder, "hint_metrics"));
|
||||
text_radio = GTK_WIDGET (gtk_builder_get_object (builder, "text_radio"));
|
||||
show_grid = GTK_WIDGET (gtk_builder_get_object (builder, "show_grid"));
|
||||
show_extents = GTK_WIDGET (gtk_builder_get_object (builder, "show_extents"));
|
||||
|
||||
g_signal_connect (up_button, "clicked", G_CALLBACK (scale_up), NULL);
|
||||
g_signal_connect (down_button, "clicked", G_CALLBACK (scale_down), NULL);
|
||||
g_signal_connect (entry, "notify::text", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (font_button, "notify::font-desc", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hinting, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (hint_metrics, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (text_radio, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (show_grid, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
g_signal_connect (show_extents, "notify::active", G_CALLBACK (update_image), NULL);
|
||||
|
||||
update_image ();
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -1,216 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkAdjustment" id="scale_adj">
|
||||
<property name="upper">24</property>
|
||||
<property name="step-increment">1</property>
|
||||
<property name="page-increment">4</property>
|
||||
</object>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="default-width">600</property>
|
||||
<property name="default-height">300</property>
|
||||
<property name="title">Font rendering</property>
|
||||
<child>
|
||||
<object class="GtkGrid">
|
||||
<property name="margin-top">10</property>
|
||||
<property name="row-spacing">10</property>
|
||||
<property name="column-spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Text</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="entry">
|
||||
<property name="text">Fonts render</property>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="margin-start">10</property>
|
||||
<property name="label">Font</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFontButton" id="font_button">
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hinting</property>
|
||||
<property name="xalign">1</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkComboBoxText" id="hinting">
|
||||
<property name="active">0</property>
|
||||
<property name="valign">center</property>
|
||||
<items>
|
||||
<item translatable="yes" id="none">None</item>
|
||||
<item translatable="yes" id="slight">Slight</item>
|
||||
<item translatable="yes" id="medium">Medium</item>
|
||||
<item translatable="yes" id="full">Full</item>
|
||||
</items>
|
||||
<layout>
|
||||
<property name="left-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="hint_metrics">
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Hint Metrics</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">3</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_extents">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Show Extents</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">4</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="show_grid">
|
||||
<property name="active">1</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Show Grid</property>
|
||||
<style>
|
||||
<class name="dim-label"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">4</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="up_button">
|
||||
<property name="icon-name">list-add-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">5</property>
|
||||
<property name="top-attach">0</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="down_button">
|
||||
<property name="icon-name">list-remove-symbolic</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
<layout>
|
||||
<property name="left-attach">5</property>
|
||||
<property name="top-attach">1</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="hexpand">1</property>
|
||||
<layout>
|
||||
<property name="left-attach">6</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="text_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<property name="label">Text</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="grid_radio">
|
||||
<property name="draw-indicator">0</property>
|
||||
<property name="label">Grid</property>
|
||||
<property name="group">text_radio</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">3</property>
|
||||
<property name="column-span">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="propagate-natural-height">1</property>
|
||||
<property name="shadow-type">in</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="vexpand">1</property>
|
||||
<child>
|
||||
<object class="GtkPicture" id="image">
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="can-shrink">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">4</property>
|
||||
<property name="column-span">7</property>
|
||||
</layout>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@@ -262,7 +262,7 @@ draw_menu (GtkWidget *widget,
|
||||
gint toggle_x, toggle_y, toggle_width, toggle_height;
|
||||
|
||||
/* This information is taken from the GtkMenu docs, see "CSS nodes" */
|
||||
menu_context = get_style (NULL, "menu");
|
||||
menu_context = get_style (gtk_widget_get_style_context(widget), "menu");
|
||||
hovermenuitem_context = get_style (menu_context, "menuitem:hover");
|
||||
hoveredarrowmenuitem_context = get_style (hovermenuitem_context, "arrow.right:dir(ltr)");
|
||||
menuitem_context = get_style (menu_context, "menuitem");
|
||||
@@ -414,7 +414,7 @@ draw_menubar (GtkWidget *widget,
|
||||
frame_context = get_style (NULL, "frame");
|
||||
border_context = get_style (frame_context, "border");
|
||||
|
||||
/* This information is taken from the GtkPopoverMenuBar docs, see "CSS nodes" */
|
||||
/* This information is taken from the GtkMenuBar docs, see "CSS nodes" */
|
||||
menubar_context = get_style (NULL, "menubar");
|
||||
hovered_menuitem_context = get_style (menubar_context, "menuitem:hover");
|
||||
menuitem_context = get_style (menubar_context, "menuitem");
|
||||
@@ -829,6 +829,7 @@ draw_spinbutton (GtkWidget *widget,
|
||||
GtkStyleContext *down_context;
|
||||
GtkIconTheme *icon_theme;
|
||||
GtkIconInfo *icon_info;
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkTexture *texture;
|
||||
gint icon_width, icon_height, icon_size;
|
||||
gint button_width;
|
||||
@@ -856,22 +857,26 @@ draw_spinbutton (GtkWidget *widget,
|
||||
"min-width", &icon_width, "min-height", &icon_height, NULL);
|
||||
icon_size = MIN (icon_width, icon_height);
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-add-symbolic", icon_size, 0);
|
||||
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (icon_info, up_context, NULL, NULL));
|
||||
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, up_context, NULL, NULL);
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
g_object_unref (icon_info);
|
||||
draw_style_common (up_context, cr, x + width - button_width, y, button_width, *height,
|
||||
&contents_x, &contents_y, &contents_width, &contents_height);
|
||||
gtk_render_icon (up_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (texture);
|
||||
|
||||
gtk_style_context_get (down_context,
|
||||
"min-width", &icon_width, "min-height", &icon_height, NULL);
|
||||
icon_size = MIN (icon_width, icon_height);
|
||||
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "list-remove-symbolic", icon_size, 0);
|
||||
texture = GDK_TEXTURE (gtk_icon_info_load_symbolic_for_context (icon_info, down_context, NULL, NULL));
|
||||
pixbuf = gtk_icon_info_load_symbolic_for_context (icon_info, down_context, NULL, NULL);
|
||||
texture = gdk_texture_new_for_pixbuf (pixbuf);
|
||||
g_object_unref (icon_info);
|
||||
draw_style_common (down_context, cr, x + width - 2 * button_width, y, button_width, *height,
|
||||
&contents_x, &contents_y, &contents_width, &contents_height);
|
||||
gtk_render_icon (down_context, cr, texture, contents_x, contents_y + (contents_height - icon_size) / 2);
|
||||
g_object_unref (pixbuf);
|
||||
g_object_unref (texture);
|
||||
|
||||
g_object_unref (down_context);
|
||||
|
@@ -94,12 +94,9 @@ drawing_area_draw (GtkDrawingArea *area,
|
||||
cairo_pattern_t *pat;
|
||||
cairo_matrix_t matrix;
|
||||
gdouble angle, scale;
|
||||
gdouble x_center, y_center;
|
||||
|
||||
gtk_gesture_get_bounding_box_center (GTK_GESTURE (zoom), &x_center, &y_center);
|
||||
|
||||
cairo_get_matrix (cr, &matrix);
|
||||
cairo_matrix_translate (&matrix, x_center, y_center);
|
||||
cairo_matrix_translate (&matrix, width / 2, height / 2);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
|
@@ -241,7 +241,7 @@ realize (GtkWidget *widget)
|
||||
fragment_path = "/glarea/glarea-gl.fs.glsl";
|
||||
}
|
||||
|
||||
init_buffers (NULL, &position_buffer);
|
||||
init_buffers (&position_buffer, NULL);
|
||||
init_shaders (vertex_path, fragment_path, &program, &mvp_location);
|
||||
}
|
||||
|
||||
|
@@ -53,7 +53,6 @@ enum {
|
||||
PROP_BENCHMARK,
|
||||
PROP_COUNT,
|
||||
PROP_FRAMERATE,
|
||||
PROP_FRAMERATE_STRING,
|
||||
PROP_UPDATE_DELAY,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
@@ -67,6 +66,8 @@ gtk_fishbowl_init (GtkFishbowl *fishbowl)
|
||||
{
|
||||
GtkFishbowlPrivate *priv = gtk_fishbowl_get_instance_private (fishbowl);
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (fishbowl), FALSE);
|
||||
|
||||
priv->update_delay = G_USEC_PER_SEC;
|
||||
}
|
||||
|
||||
@@ -289,14 +290,6 @@ gtk_fishbowl_get_property (GObject *object,
|
||||
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;
|
||||
@@ -350,13 +343,6 @@ gtk_fishbowl_class_init (GtkFishbowlClass *klass)
|
||||
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",
|
||||
@@ -505,10 +491,7 @@ gtk_fishbowl_do_update (GtkFishbowl *fishbowl)
|
||||
|
||||
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;
|
||||
|
@@ -41,7 +41,6 @@ show_page (GtkTextBuffer *buffer,
|
||||
|
||||
gtk_text_buffer_set_text (buffer, "", 0);
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
if (page == 1)
|
||||
{
|
||||
gtk_text_buffer_insert (buffer, &iter, "Some text to show that simple ", -1);
|
||||
@@ -74,7 +73,6 @@ show_page (GtkTextBuffer *buffer,
|
||||
"so that related items of information are connected.\n", -1);
|
||||
insert_link (buffer, &iter, "Go back", 1);
|
||||
}
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
}
|
||||
|
||||
/* Looks at all tags covering the position of iter in the text view,
|
||||
@@ -138,11 +136,11 @@ static void set_cursor_if_appropriate (GtkTextView *text_view,
|
||||
gint y);
|
||||
|
||||
static void
|
||||
released_cb (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *text_view)
|
||||
released_cb (GtkGestureMultiPress *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *text_view)
|
||||
{
|
||||
GtkTextIter start, end, iter;
|
||||
GtkTextBuffer *buffer;
|
||||
@@ -249,7 +247,7 @@ do_hypertext (GtkWidget *do_widget)
|
||||
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 ());
|
||||
controller = GTK_EVENT_CONTROLLER (gtk_gesture_multi_press_new ());
|
||||
g_signal_connect (controller, "released",
|
||||
G_CALLBACK (released_cb), view);
|
||||
gtk_widget_add_controller (view, controller);
|
||||
@@ -260,7 +258,6 @@ do_hypertext (GtkWidget *do_widget)
|
||||
gtk_widget_add_controller (view, controller);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_set_enable_undo (buffer, TRUE);
|
||||
|
||||
sw = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||
|
@@ -1,229 +0,0 @@
|
||||
/* Benchmark/Scrolling
|
||||
*
|
||||
* This demo scrolls a view with various content.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static guint tick_cb;
|
||||
static GtkAdjustment *hadjustment;
|
||||
static GtkAdjustment *vadjustment;
|
||||
static GtkWidget *window = NULL;
|
||||
static GtkWidget *scrolledwindow;
|
||||
static int selected;
|
||||
|
||||
#define N_WIDGET_TYPES 4
|
||||
|
||||
|
||||
static int hincrement = 5;
|
||||
static int vincrement = 5;
|
||||
|
||||
static gboolean
|
||||
scroll_cb (GtkWidget *widget,
|
||||
GdkFrameClock *frame_clock,
|
||||
gpointer data)
|
||||
{
|
||||
double value;
|
||||
|
||||
value = gtk_adjustment_get_value (vadjustment);
|
||||
if (value + vincrement <= gtk_adjustment_get_lower (vadjustment) ||
|
||||
(value + vincrement >= gtk_adjustment_get_upper (vadjustment) - gtk_adjustment_get_page_size (vadjustment)))
|
||||
vincrement = - vincrement;
|
||||
|
||||
gtk_adjustment_set_value (vadjustment, value + vincrement);
|
||||
|
||||
value = gtk_adjustment_get_value (hadjustment);
|
||||
if (value + hincrement <= gtk_adjustment_get_lower (hadjustment) ||
|
||||
(value + hincrement >= gtk_adjustment_get_upper (hadjustment) - gtk_adjustment_get_page_size (hadjustment)))
|
||||
hincrement = - hincrement;
|
||||
|
||||
gtk_adjustment_set_value (hadjustment, value + hincrement);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
extern GtkWidget *create_icon (void);
|
||||
|
||||
static void
|
||||
populate_icons (void)
|
||||
{
|
||||
GtkWidget *grid;
|
||||
int top, left;
|
||||
|
||||
grid = gtk_grid_new ();
|
||||
gtk_widget_set_halign (grid, GTK_ALIGN_CENTER);
|
||||
g_object_set (grid, "margin", 10, NULL);
|
||||
gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
|
||||
gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
|
||||
|
||||
for (top = 0; top < 100; top++)
|
||||
for (left = 0; left < 15; left++)
|
||||
gtk_grid_attach (GTK_GRID (grid), create_icon (), left, top, 1, 1);
|
||||
|
||||
hincrement = 0;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), grid);
|
||||
}
|
||||
|
||||
static char *content;
|
||||
static gsize content_len;
|
||||
|
||||
extern void fontify (GtkTextBuffer *buffer);
|
||||
|
||||
static void
|
||||
populate_text (gboolean hilight)
|
||||
{
|
||||
GtkWidget *textview;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
if (!content)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
|
||||
content = g_bytes_unref_to_data (bytes, &content_len);
|
||||
}
|
||||
|
||||
buffer = gtk_text_buffer_new (NULL);
|
||||
gtk_text_buffer_set_text (buffer, content, (int)content_len);
|
||||
|
||||
if (hilight)
|
||||
fontify (buffer);
|
||||
|
||||
textview = gtk_text_view_new ();
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (textview), buffer);
|
||||
|
||||
hincrement = 0;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_NEVER,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), textview);
|
||||
}
|
||||
|
||||
static void
|
||||
populate_image (void)
|
||||
{
|
||||
GtkWidget *image;
|
||||
|
||||
if (!content)
|
||||
{
|
||||
GBytes *bytes;
|
||||
|
||||
bytes = g_resources_lookup_data ("/sources/font_features.c", 0, NULL);
|
||||
content = g_bytes_unref_to_data (bytes, &content_len);
|
||||
}
|
||||
|
||||
image = gtk_picture_new_for_resource ("/sliding_puzzle/portland-rose.jpg");
|
||||
gtk_picture_set_can_shrink (GTK_PICTURE (image), FALSE);
|
||||
|
||||
hincrement = 5;
|
||||
|
||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
|
||||
GTK_POLICY_AUTOMATIC,
|
||||
GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add (GTK_CONTAINER (scrolledwindow), image);
|
||||
}
|
||||
|
||||
static void
|
||||
set_widget_type (int type)
|
||||
{
|
||||
if (tick_cb)
|
||||
gtk_widget_remove_tick_callback (window, tick_cb);
|
||||
|
||||
if (gtk_bin_get_child (GTK_BIN (scrolledwindow)))
|
||||
gtk_container_remove (GTK_CONTAINER (scrolledwindow),
|
||||
gtk_bin_get_child (GTK_BIN (scrolledwindow)));
|
||||
|
||||
selected = type;
|
||||
|
||||
switch (selected)
|
||||
{
|
||||
case 0:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling icons");
|
||||
populate_icons ();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling plain text");
|
||||
populate_text (FALSE);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling complex text");
|
||||
populate_text (TRUE);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Scrolling a big image");
|
||||
populate_image ();
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
tick_cb = gtk_widget_add_tick_callback (window, scroll_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
iconscroll_next_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
int new_index;
|
||||
|
||||
if (selected + 1 >= N_WIDGET_TYPES)
|
||||
new_index = 0;
|
||||
else
|
||||
new_index = selected + 1;
|
||||
|
||||
|
||||
set_widget_type (new_index);
|
||||
}
|
||||
|
||||
void
|
||||
iconscroll_prev_clicked_cb (GtkButton *source,
|
||||
gpointer user_data)
|
||||
{
|
||||
int new_index;
|
||||
|
||||
if (selected - 1 < 0)
|
||||
new_index = N_WIDGET_TYPES - 1;
|
||||
else
|
||||
new_index = selected - 1;
|
||||
|
||||
set_widget_type (new_index);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_iconscroll (GtkWidget *do_widget)
|
||||
{
|
||||
if (!window)
|
||||
{
|
||||
GtkBuilder *builder;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/iconscroll/iconscroll.ui");
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
scrolledwindow = GTK_WIDGET (gtk_builder_get_object (builder, "scrolledwindow"));
|
||||
gtk_widget_realize (window);
|
||||
hadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hadjustment"));
|
||||
vadjustment = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "vadjustment"));
|
||||
set_widget_type (0);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window">
|
||||
<property name="resizable">0</property>
|
||||
<property name="default-width">500</property>
|
||||
<property name="default-height">500</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<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="iconscroll_prev_clicked_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">pan-end-symbolic</property>
|
||||
<signal name="clicked" handler="iconscroll_next_clicked_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolledwindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="hadjustment">
|
||||
<object class="GtkAdjustment" id="hadjustment"/>
|
||||
</property>
|
||||
<property name="vadjustment">
|
||||
<object class="GtkAdjustment" id="vadjustment"/>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
@@ -20,7 +20,7 @@ on_bar_response (GtkInfoBar *info_bar,
|
||||
return;
|
||||
}
|
||||
|
||||
window = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (info_bar)));
|
||||
window = gtk_widget_get_toplevel (GTK_WIDGET (info_bar));
|
||||
dialog = gtk_message_dialog_new (GTK_WINDOW (window),
|
||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
@@ -68,7 +68,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_INFO);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_INFO");
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
@@ -80,7 +80,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_WARNING);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_WARNING");
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
@@ -94,10 +94,9 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_QUESTION);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_QUESTION");
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
gtk_info_bar_set_default_response (GTK_INFO_BAR (bar), GTK_RESPONSE_OK);
|
||||
|
||||
button = gtk_toggle_button_new_with_label ("Question");
|
||||
g_object_bind_property (bar, "revealed", button, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
@@ -107,7 +106,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_ERROR);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_ERROR");
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
@@ -120,7 +119,7 @@ do_infobar (GtkWidget *do_widget)
|
||||
gtk_container_add (GTK_CONTAINER (vbox), bar);
|
||||
gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_OTHER);
|
||||
label = gtk_label_new ("This is an info bar with message type GTK_MESSAGE_OTHER");
|
||||
gtk_label_set_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
|
||||
|
||||
|
@@ -18,10 +18,6 @@
|
||||
|
||||
#include "language-names.h"
|
||||
|
||||
#ifndef ISO_CODES_PREFIX
|
||||
#define ISO_CODES_PREFIX "/usr"
|
||||
#endif
|
||||
|
||||
#define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes"
|
||||
#define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale"
|
||||
|
||||
@@ -206,7 +202,7 @@ languages_variant_init (const char *variant)
|
||||
else
|
||||
g_warning ("Failed to load '%s': %s\n", filename, error->message);
|
||||
|
||||
g_clear_error (&error);
|
||||
g_free (error);
|
||||
g_free (filename);
|
||||
g_free (buf);
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ activate_link (GtkWidget *label,
|
||||
GtkWidget *dialog;
|
||||
GtkWidget *parent;
|
||||
|
||||
parent = GTK_WIDGET (gtk_widget_get_root (label));
|
||||
parent = gtk_widget_get_toplevel (label);
|
||||
dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (parent),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_INFO,
|
||||
|
@@ -1,15 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface domain="gtk40">
|
||||
<menu id="menu1">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Email message</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Embed message</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<object class="GtkMenu" id="menu1">
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem1">
|
||||
<property name="label" translatable="yes">Email message</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuitem2">
|
||||
<property name="label" translatable="yes">Embed message</property>
|
||||
<property name="use-underline">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<template class="GtkMessageRow" parent="GtkListBoxRow">
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid1">
|
||||
@@ -25,12 +28,12 @@
|
||||
<property name="margin-start">8</property>
|
||||
<property name="margin-end">8</property>
|
||||
<property name="icon-name">image-missing</property>
|
||||
<layout>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="row-span">5</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">0</property>
|
||||
<property name="top-attach">0</property>
|
||||
<property name="height">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
@@ -71,11 +74,11 @@
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<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="content_label">
|
||||
@@ -88,11 +91,11 @@
|
||||
<accessibility>
|
||||
<role type="static"/>
|
||||
</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="GtkBox" id="resent_box">
|
||||
@@ -115,11 +118,11 @@
|
||||
<property name="uri">http://www.gtk.org</property>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box3">
|
||||
@@ -167,18 +170,22 @@
|
||||
<object class="GtkMenuButton" id="more-button">
|
||||
<property name="can-focus">1</property>
|
||||
<property name="receives-default">1</property>
|
||||
<property name="menu-model">menu1</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="label" translatable="yes">More...</property>
|
||||
<property name="popup">menu1</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label7">
|
||||
<property name="label" translatable="yes">More...</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRevealer" id="details_revealer">
|
||||
@@ -243,11 +250,11 @@ FAVORITES</property>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<layout>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
</layout>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left-attach">1</property>
|
||||
<property name="top-attach">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
|
@@ -45,43 +45,22 @@ activate_about (GSimpleAction *action,
|
||||
"The GTK Team",
|
||||
NULL
|
||||
};
|
||||
char *version;
|
||||
GString *s;
|
||||
|
||||
s = g_string_new ("");
|
||||
|
||||
g_string_append (s, "System libraries\n");
|
||||
g_string_append_printf (s, "\tGLib\t%d.%d.%d\n",
|
||||
glib_major_version,
|
||||
glib_minor_version,
|
||||
glib_micro_version);
|
||||
g_string_append_printf (s, "\tGTK\t%d.%d.%d\n",
|
||||
gtk_get_major_version (),
|
||||
gtk_get_minor_version (),
|
||||
gtk_get_micro_version ());
|
||||
g_string_append_printf (s, "\nA link can apppear here: <http://www.gtk.org>");
|
||||
|
||||
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 ());
|
||||
|
||||
gtk_show_about_dialog (GTK_WINDOW (gtk_application_get_active_window (app)),
|
||||
"program-name", "GTK Demo",
|
||||
"version", version,
|
||||
"copyright", "© 1997—2019 The GTK Team",
|
||||
"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",
|
||||
"license-type", GTK_LICENSE_LGPL_2_1,
|
||||
"website", "http://www.gtk.org",
|
||||
"comments", "Program to demonstrate GTK widgets",
|
||||
"authors", authors,
|
||||
"logo-icon-name", "org.gtk.Demo4",
|
||||
"logo-icon-name", "org.gtk.Demo",
|
||||
"title", "About GTK Demo",
|
||||
"system-information", s->str,
|
||||
NULL);
|
||||
|
||||
g_string_free (s, TRUE);
|
||||
g_free (version);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -105,14 +84,6 @@ activate_quit (GSimpleAction *action,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate_inspector (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_window_set_interactive_debugging (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
window_closed_cb (GtkWidget *window, gpointer data)
|
||||
{
|
||||
@@ -164,7 +135,7 @@ run_example_for_row (GtkWidget *window,
|
||||
cbdata->model = model;
|
||||
cbdata->path = gtk_tree_model_get_path (model, iter);
|
||||
|
||||
if (GTK_IS_WINDOW (demo))
|
||||
if (gtk_widget_is_toplevel (demo))
|
||||
{
|
||||
gtk_window_set_transient_for (GTK_WINDOW (demo), GTK_WINDOW (window));
|
||||
gtk_window_set_modal (GTK_WINDOW (demo), TRUE);
|
||||
@@ -487,7 +458,7 @@ parse_chars (gchar *text,
|
||||
}
|
||||
|
||||
/* While not as cool as c-mode, this will do as a quick attempt at highlighting */
|
||||
void
|
||||
static void
|
||||
fontify (GtkTextBuffer *source_buffer)
|
||||
{
|
||||
GtkTextIter start_iter, next_iter, tmp_iter;
|
||||
@@ -639,7 +610,7 @@ display_nothing (const char *resource)
|
||||
|
||||
str = g_strdup_printf ("The lazy GTK developers forgot to add a way to display the resource '%s'", resource);
|
||||
widget = gtk_label_new (str);
|
||||
gtk_label_set_wrap (GTK_LABEL (widget), TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
|
||||
|
||||
g_free (str);
|
||||
|
||||
@@ -697,7 +668,7 @@ add_data_tab (const gchar *demoname)
|
||||
gtk_widget_show (label);
|
||||
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), widget, label);
|
||||
g_object_set (gtk_notebook_get_page (GTK_NOTEBOOK (notebook), widget),
|
||||
"tab-expand", FALSE,
|
||||
"tab-expand", TRUE,
|
||||
NULL);
|
||||
|
||||
g_free (resource_name);
|
||||
@@ -748,9 +719,6 @@ load_file (const gchar *demoname,
|
||||
|
||||
source_buffer = gtk_text_buffer_new (NULL);
|
||||
|
||||
gtk_text_buffer_begin_irreversible_action (info_buffer);
|
||||
gtk_text_buffer_begin_irreversible_action (source_buffer);
|
||||
|
||||
resource_filename = g_strconcat ("/sources/", filename, NULL);
|
||||
bytes = g_resources_lookup_data (resource_filename, 0, &err);
|
||||
g_free (resource_filename);
|
||||
@@ -883,11 +851,9 @@ load_file (const gchar *demoname,
|
||||
|
||||
fontify (source_buffer);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (source_buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer);
|
||||
g_object_unref (source_buffer);
|
||||
|
||||
gtk_text_buffer_end_irreversible_action (info_buffer);
|
||||
gtk_text_view_set_buffer (GTK_TEXT_VIEW (info_view), info_buffer);
|
||||
g_object_unref (info_buffer);
|
||||
}
|
||||
@@ -996,13 +962,39 @@ row_activated_cb (GtkWidget *tree_view,
|
||||
GtkWidget *window;
|
||||
GtkTreeModel *model;
|
||||
|
||||
window = GTK_WIDGET (gtk_widget_get_root (tree_view));
|
||||
window = gtk_widget_get_toplevel (tree_view);
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
|
||||
gtk_tree_model_get_iter (model, &iter, path);
|
||||
|
||||
run_example_for_row (window, model, &iter);
|
||||
}
|
||||
|
||||
static void
|
||||
start_cb (GtkMenuItem *item, GtkWidget *scrollbar)
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
|
||||
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (scrollbar));
|
||||
gtk_adjustment_set_value (adj, gtk_adjustment_get_lower (adj));
|
||||
}
|
||||
|
||||
static void
|
||||
end_cb (GtkMenuItem *item, GtkWidget *scrollbar)
|
||||
{
|
||||
GtkAdjustment *adj;
|
||||
|
||||
adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (scrollbar));
|
||||
gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
scrollbar_popup (GtkWidget *scrollbar, GtkWidget *menu)
|
||||
{
|
||||
gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
activate (GApplication *app)
|
||||
{
|
||||
@@ -1011,12 +1003,23 @@ activate (GApplication *app)
|
||||
GtkWidget *widget;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
GError *error = NULL;
|
||||
GtkWidget *sw;
|
||||
GtkWidget *scrollbar;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *item;
|
||||
|
||||
static GActionEntry win_entries[] = {
|
||||
{ "run", activate_run, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/ui/main.ui");
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_add_from_resource (builder, "/ui/main.ui", &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
g_critical ("%s", error->message);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
window = (GtkWindow *)gtk_builder_get_object (builder, "window");
|
||||
gtk_application_add_window (GTK_APPLICATION (app), window);
|
||||
@@ -1032,6 +1035,21 @@ activate (GApplication *app)
|
||||
treeview = (GtkWidget *)gtk_builder_get_object (builder, "treeview");
|
||||
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
|
||||
|
||||
sw = (GtkWidget *)gtk_builder_get_object (builder, "source-scrolledwindow");
|
||||
scrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (sw));
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
|
||||
item = gtk_menu_item_new_with_label ("Start");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (start_cb), scrollbar);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
|
||||
item = gtk_menu_item_new_with_label ("End");
|
||||
g_signal_connect (item, "activate", G_CALLBACK (end_cb), scrollbar);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
|
||||
|
||||
g_signal_connect (scrollbar, "popup-menu", G_CALLBACK (scrollbar_popup), menu);
|
||||
|
||||
load_file (gtk_demos[0].name, gtk_demos[0].filename);
|
||||
|
||||
populate_model (model);
|
||||
@@ -1182,7 +1200,6 @@ main (int argc, char **argv)
|
||||
static GActionEntry app_entries[] = {
|
||||
{ "about", activate_about, NULL, NULL, NULL },
|
||||
{ "quit", activate_quit, NULL, NULL, NULL },
|
||||
{ "inspector", activate_inspector, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
/* Most code in gtk-demo is intended to be exemplary, but not
|
||||
@@ -1195,7 +1212,7 @@ main (int argc, char **argv)
|
||||
}
|
||||
/* -- End of hack -- */
|
||||
|
||||
app = gtk_application_new ("org.gtk.Demo4", G_APPLICATION_NON_UNIQUE|G_APPLICATION_HANDLES_COMMAND_LINE);
|
||||
app = gtk_application_new ("org.gtk.Demo", G_APPLICATION_NON_UNIQUE|G_APPLICATION_HANDLES_COMMAND_LINE);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (app),
|
||||
app_entries, G_N_ELEMENTS (app_entries),
|
||||
|
@@ -1,17 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="gear_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_Inspector</attribute>
|
||||
<attribute name="action">app.inspector</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">_About GTK Demo</attribute>
|
||||
<attribute name="action">app.about</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<object class="GtkTreeStore" id="treestore">
|
||||
<columns>
|
||||
<column type="gchararray"/>
|
||||
@@ -47,13 +34,6 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton" id="gear_menu_button">
|
||||
<property name="valign">center</property>
|
||||
<property name="menu-model">gear_menu</property>
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@@ -29,10 +29,8 @@ source_toggled (GtkToggleButton *button)
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_bounds (buffer, &start, &end);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_delete (buffer, &start, &end);
|
||||
gtk_text_buffer_insert_markup (buffer, &start, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
g_free (markup);
|
||||
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), "formatted");
|
||||
@@ -108,15 +106,11 @@ do_markup (GtkWidget *do_widget)
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert_markup (buffer, &iter, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view2));
|
||||
gtk_text_buffer_get_start_iter (buffer, &iter);
|
||||
gtk_text_buffer_begin_irreversible_action (buffer);
|
||||
gtk_text_buffer_insert (buffer, &iter, markup, -1);
|
||||
gtk_text_buffer_end_irreversible_action (buffer);
|
||||
|
||||
g_bytes_unref (bytes);
|
||||
|
||||
|
163
demos/gtk-demo/menus.c
Normal file
163
demos/gtk-demo/menus.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/* Menus
|
||||
*
|
||||
* There are several widgets involved in displaying menus. The
|
||||
* GtkMenuBar widget is a menu bar, which normally appears horizontally
|
||||
* at the top of an application, but can also be layed out vertically.
|
||||
* The GtkMenu widget is the actual menu that pops up. Both GtkMenuBar
|
||||
* and GtkMenu are subclasses of GtkMenuShell; a GtkMenuShell contains
|
||||
* menu items (GtkMenuItem). Each menu item contains text and/or images
|
||||
* and can be selected by the user.
|
||||
*
|
||||
* There are several kinds of menu item, including plain GtkMenuItem,
|
||||
* GtkCheckMenuItem which can be checked/unchecked, GtkRadioMenuItem
|
||||
* which is a check menu item that's in a mutually exclusive group,
|
||||
* GtkSeparatorMenuItem which is a separator bar, GtkTearoffMenuItem
|
||||
* which allows a GtkMenu to be torn off, and GtkImageMenuItem which
|
||||
* can place a GtkImage or other widget next to the menu text.
|
||||
*
|
||||
* A GtkMenuItem can have a submenu, which is simply a GtkMenu to pop
|
||||
* up when the menu item is selected. Typically, all menu items in a menu bar
|
||||
* have submenus.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static GtkWidget *
|
||||
create_menu (gint depth)
|
||||
{
|
||||
GtkWidget *menu;
|
||||
GtkRadioMenuItem *last_item;
|
||||
char buf[32];
|
||||
int i, j;
|
||||
|
||||
if (depth < 1)
|
||||
return NULL;
|
||||
|
||||
menu = gtk_menu_new ();
|
||||
last_item = NULL;
|
||||
|
||||
for (i = 0, j = 1; i < 5; i++, j++)
|
||||
{
|
||||
GtkWidget *menu_item;
|
||||
|
||||
sprintf (buf, "item %2d - %d", depth, j);
|
||||
|
||||
menu_item = gtk_radio_menu_item_new_with_label_from_widget (NULL, buf);
|
||||
gtk_radio_menu_item_join_group (GTK_RADIO_MENU_ITEM (menu_item), last_item);
|
||||
last_item = GTK_RADIO_MENU_ITEM (menu_item);
|
||||
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
|
||||
gtk_widget_show (menu_item);
|
||||
if (i == 3)
|
||||
gtk_widget_set_sensitive (menu_item, FALSE);
|
||||
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), create_menu (depth - 1));
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static void
|
||||
change_orientation (GtkWidget *button,
|
||||
GtkWidget *menubar)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
GtkOrientation orientation;
|
||||
|
||||
parent = gtk_widget_get_parent (menubar);
|
||||
orientation = gtk_orientable_get_orientation (GTK_ORIENTABLE (parent));
|
||||
gtk_orientable_set_orientation (GTK_ORIENTABLE (parent), 1 - orientation);
|
||||
|
||||
if (orientation == GTK_ORIENTATION_VERTICAL)
|
||||
g_object_set (menubar, "pack-direction", GTK_PACK_DIRECTION_TTB, NULL);
|
||||
else
|
||||
g_object_set (menubar, "pack-direction", GTK_PACK_DIRECTION_LTR, NULL);
|
||||
|
||||
}
|
||||
|
||||
static GtkWidget *window = NULL;
|
||||
|
||||
GtkWidget *
|
||||
do_menus (GtkWidget *do_widget)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *box1;
|
||||
GtkWidget *box2;
|
||||
GtkWidget *button;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *menubar;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *menuitem;
|
||||
GtkAccelGroup *accel_group;
|
||||
|
||||
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), "Menus");
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK(gtk_widget_destroyed), &window);
|
||||
|
||||
accel_group = gtk_accel_group_new ();
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
gtk_widget_show (box);
|
||||
|
||||
box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (box), box1);
|
||||
gtk_widget_show (box1);
|
||||
|
||||
menubar = gtk_menu_bar_new ();
|
||||
gtk_widget_set_hexpand (menubar, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box1), menubar);
|
||||
gtk_widget_show (menubar);
|
||||
|
||||
menu = create_menu (2);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("test\nline2");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("foo");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (3));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
menuitem = gtk_menu_item_new_with_label ("bar");
|
||||
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (4));
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
|
||||
gtk_widget_show (menuitem);
|
||||
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (box1), box2);
|
||||
gtk_widget_show (box2);
|
||||
|
||||
button = gtk_button_new_with_label ("Flip");
|
||||
g_signal_connect (button, "clicked",
|
||||
G_CALLBACK (change_orientation), menubar);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK(gtk_widget_destroy), window);
|
||||
gtk_container_add (GTK_CONTAINER (box2), button);
|
||||
gtk_widget_set_can_default (button, TRUE);
|
||||
gtk_widget_grab_default (button);
|
||||
gtk_widget_show (button);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="appmenu">
|
||||
<section>
|
||||
|
@@ -4,12 +4,10 @@ demos = files([
|
||||
'application_demo.c',
|
||||
'assistant.c',
|
||||
'builder.c',
|
||||
'changedisplay.c',
|
||||
'clipboard.c',
|
||||
'colorsel.c',
|
||||
'combobox.c',
|
||||
'constraints.c',
|
||||
'constraints2.c',
|
||||
'constraints3.c',
|
||||
'css_accordion.c',
|
||||
'css_basics.c',
|
||||
'css_blendmodes.c',
|
||||
@@ -21,19 +19,16 @@ demos = files([
|
||||
'drawingarea.c',
|
||||
'dnd.c',
|
||||
'editable_cells.c',
|
||||
'entry_buffer.c',
|
||||
'entry_completion.c',
|
||||
'entry_undo.c',
|
||||
'expander.c',
|
||||
'filtermodel.c',
|
||||
'fishbowl.c',
|
||||
'fixed.c',
|
||||
'fontrendering.c',
|
||||
'foreigndrawing.c',
|
||||
'gestures.c',
|
||||
'glarea.c',
|
||||
'headerbar.c',
|
||||
'hypertext.c',
|
||||
'iconscroll.c',
|
||||
'iconview.c',
|
||||
'iconview_edit.c',
|
||||
'images.c',
|
||||
@@ -43,6 +38,7 @@ demos = files([
|
||||
'flowbox.c',
|
||||
'list_store.c',
|
||||
'markup.c',
|
||||
'menus.c',
|
||||
'modelbutton.c',
|
||||
'overlay.c',
|
||||
'overlay2.c',
|
||||
@@ -71,10 +67,8 @@ demos = files([
|
||||
'tabs.c',
|
||||
'tagged_entry.c',
|
||||
'textmask.c',
|
||||
'textundo.c',
|
||||
'textview.c',
|
||||
'textscroll.c',
|
||||
'themes.c',
|
||||
'theming_style_classes.c',
|
||||
'transparent.c',
|
||||
'tree_store.c',
|
||||
@@ -140,11 +134,11 @@ foreach size: ['scalable', 'symbolic']
|
||||
endforeach
|
||||
|
||||
# desktop file
|
||||
install_data('org.gtk.Demo4.desktop', install_dir: gtk_applicationsdir)
|
||||
install_data('org.gtk.Demo.desktop', install_dir: gtk_applicationsdir)
|
||||
|
||||
# GSettings
|
||||
install_data('org.gtk.Demo4.gschema.xml', install_dir: gtk_schemasdir)
|
||||
install_data('org.gtk.Demo.gschema.xml', install_dir: gtk_schemasdir)
|
||||
gnome.compile_schemas()
|
||||
|
||||
# appdata
|
||||
install_data('org.gtk.Demo4.appdata.xml', install_dir: gtk_appdatadir)
|
||||
install_data('org.gtk.Demo.appdata.xml', install_dir: gtk_appdatadir)
|
||||
|
@@ -378,7 +378,7 @@
|
||||
378|GTK+ and friends|GTKtoolkit|#GNUStep gets #GTK+ theming http://is.gd/95vHl more at http://is.gd/95wt8|1267029498|0||0|1
|
||||
379|GTK+ and friends|GTKtoolkit|GTK+ 2.19.6 released: http://mail.gnome.org/archives/gtk-devel-list/2010-February/msg00050.html #gtk|1266966985|0||0|0
|
||||
380|GTK+ and friends|GTKtoolkit|Did you know that #GTK+ is the official toolkit for the #LiMo software stack? http://bit.ly/cuEdHx|1266925406|0||0|0
|
||||
381|GTK+ and friends|GTKtoolkit|@lmedinas publishes a #javascript #example on how to put a status icon with #Gtk+ http://bit.ly/9py1uC Thanks a lot Luis!|1266886644|0||1|1
|
||||
381|GTK+ and friends|GTKtoolkit|@lmedinas publishes a #javascript #example on how to put an status icon with #Gtk+ http://bit.ly/9py1uC Thanks a lot Luis!|1266886644|0||1|1
|
||||
382|GTK+ and friends|GTKtoolkit|♺ @ebassi: I should really finish up the GDom API as well|1266880653|0||0|0
|
||||
383|GTK+ and friends|GTKtoolkit|♺ @ebassi: I hope to work on this for the next GIO release, and the GTK+ side for 3.0|1266880641|0||0|0
|
||||
384|GTK+ and friends|GTKtoolkit|♺ @ebassi: just updated the ApplicationClass design wiki page with the stuff @Cwiiis did for Mx - http://bit.ly/cfAOJk|1266880559|0||0|0
|
||||
|
@@ -14,8 +14,8 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
void
|
||||
modelbutton_tool_clicked (GtkButton *button)
|
||||
static void
|
||||
tool_clicked (GtkButton *button)
|
||||
{
|
||||
gboolean active;
|
||||
|
||||
@@ -40,6 +40,8 @@ do_modelbutton (GtkWidget *do_widget)
|
||||
GActionGroup *actions;
|
||||
|
||||
builder = gtk_builder_new_from_resource ("/modelbutton/modelbutton.ui");
|
||||
gtk_builder_add_callback_symbol (builder, "tool_clicked", G_CALLBACK (tool_clicked));
|
||||
gtk_builder_connect_signals (builder, NULL);
|
||||
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
|
||||
gtk_window_set_display (GTK_WINDOW (window),
|
||||
gtk_widget_get_display (do_widget));
|
||||
|
@@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<object class="GtkWindow" id="window1">
|
||||
<child type="titlebar">
|
||||
@@ -14,19 +13,34 @@
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_a</property>
|
||||
<property name="label">Color</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Color</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_b</property>
|
||||
<property name="label">Flavors</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Flavors</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<property name="popover">thing_c</property>
|
||||
<property name="label">Tools</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Tools</property>
|
||||
<property name="hexpand">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -42,6 +56,7 @@
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'red'</property>
|
||||
<property name="text">Red</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -49,6 +64,7 @@
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'green'</property>
|
||||
<property name="text">Green</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -56,6 +72,7 @@
|
||||
<property name="action-name">win.color</property>
|
||||
<property name="action-target">'blue'</property>
|
||||
<property name="text">Blue</property>
|
||||
<property name="inverted">1</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -101,21 +118,21 @@
|
||||
<object class="GtkModelButton">
|
||||
<property name="text">Hammer</property>
|
||||
<property name="role">check</property>
|
||||
<signal name="clicked" handler="modelbutton_tool_clicked"/>
|
||||
<signal name="clicked" handler="tool_clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="text">Screwdriver</property>
|
||||
<property name="role">check</property>
|
||||
<signal name="clicked" handler="modelbutton_tool_clicked"/>
|
||||
<signal name="clicked" handler="tool_clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="text">Drill</property>
|
||||
<property name="role">check</property>
|
||||
<signal name="clicked" handler="modelbutton_tool_clicked"/>
|
||||
<signal name="clicked" handler="tool_clicked"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>org.gtk.Demo4.desktop</id>
|
||||
<id>org.gtk.Demo.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>LGPL-2.0+</project_license>
|
||||
<name>GTK Demo</name>
|
@@ -2,7 +2,7 @@
|
||||
Name=GTK Demo
|
||||
Comment=GTK code examples and demonstrations
|
||||
Exec=gtk4-demo
|
||||
Icon=org.gtk.Demo4
|
||||
Icon=org.gtk.Demo
|
||||
Terminal=false
|
||||
Type=Application
|
||||
StartupNotify=true
|
@@ -2,14 +2,14 @@
|
||||
|
||||
<schemalist>
|
||||
|
||||
<enum id='org.gtk.Demo4.Color'>
|
||||
<enum id='org.gtk.Demo.Color'>
|
||||
<value nick='red' value='0'/>
|
||||
<value nick='green' value='1'/>
|
||||
<value nick='blue' value='2'/>
|
||||
</enum>
|
||||
|
||||
<schema id='org.gtk.Demo4' path='/org/gtk/Demo4/'>
|
||||
<key name='color' enum='org.gtk.Demo4.Color'>
|
||||
<schema id='org.gtk.Demo' path='/org/gtk/Demo/'>
|
||||
<key name='color' enum='org.gtk.Demo.Color'>
|
||||
<default>'red'</default>
|
||||
</key>
|
||||
<key name='window-size' type='(ii)'>
|
@@ -57,7 +57,7 @@ do_overlay (GtkWidget *do_widget)
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), vbox);
|
||||
gtk_widget_set_can_target (vbox, FALSE);
|
||||
gtk_widget_set_can_pick (vbox, FALSE);
|
||||
gtk_widget_set_halign (vbox, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (vbox, GTK_ALIGN_CENTER);
|
||||
|
||||
|
@@ -66,13 +66,13 @@ do_overlay2 (GtkWidget *do_widget)
|
||||
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor1.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_widget_set_can_target (image, FALSE);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_START);
|
||||
|
||||
image = gtk_picture_new_for_resource ("/overlay2/decor2.png");
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), image);
|
||||
gtk_widget_set_can_target (image, FALSE);
|
||||
gtk_widget_set_can_pick (image, FALSE);
|
||||
gtk_widget_set_halign (image, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (image, GTK_ALIGN_END);
|
||||
|
||||
|
@@ -176,7 +176,7 @@ drawing_area_unroot (GtkWidget *widget)
|
||||
DrawingArea *area = (DrawingArea *) widget;
|
||||
GtkWidget *toplevel;
|
||||
|
||||
toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
|
||||
toplevel = gtk_widget_get_toplevel (widget);
|
||||
|
||||
if (area->pad_controller)
|
||||
{
|
||||
@@ -198,7 +198,7 @@ drawing_area_root (GtkWidget *widget)
|
||||
|
||||
GTK_WIDGET_CLASS (drawing_area_parent_class)->root (widget);
|
||||
|
||||
toplevel = GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (area)));
|
||||
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (area));
|
||||
|
||||
action_group = g_simple_action_group_new ();
|
||||
area->pad_controller = gtk_pad_controller_new (G_ACTION_GROUP (action_group), NULL);
|
||||
@@ -330,6 +330,8 @@ drawing_area_init (DrawingArea *area)
|
||||
{
|
||||
GtkGesture *gesture;
|
||||
|
||||
gtk_widget_set_has_surface (GTK_WIDGET (area), FALSE);
|
||||
|
||||
gesture = gtk_gesture_stylus_new ();
|
||||
g_signal_connect (gesture, "down",
|
||||
G_CALLBACK (stylus_gesture_down), area);
|
||||
|
@@ -6,7 +6,7 @@
|
||||
* GTK uses for videos. This allows treating the icon like a
|
||||
* regular video, so we can for example attach controls to it.
|
||||
*
|
||||
* After all, what good is a media_stream if one cannot pause
|
||||
* After all, what good is an media_stream if one cannot pause
|
||||
* it.
|
||||
*/
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user