Merge branch 'release-0.1.0'
This commit is contained in:
commit
b02cfef370
|
@ -0,0 +1,6 @@
|
||||||
|
[submodule "cmake/backbone"]
|
||||||
|
path = cmake/backbone
|
||||||
|
url = git@git.backbone.ws:make/cmake-backbone-modules.git
|
||||||
|
[submodule "util/backbone-utils"]
|
||||||
|
path = util/backbone
|
||||||
|
url = git@git.backbone.ws:make/cmake-backbone-utils.git
|
|
@ -0,0 +1,21 @@
|
||||||
|
PROJECT (CairoChart C)
|
||||||
|
|
||||||
|
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
|
||||||
|
|
||||||
|
SET (PROJECT_LOWERCASE_NAME "cairo-chart")
|
||||||
|
SET (PROJECT_DESCRIPTION "GtkChart for Gtk.DrawingArea (Cairo).")
|
||||||
|
|
||||||
|
SET (MAJOR 0)
|
||||||
|
SET (MINOR 1)
|
||||||
|
SET (PATCH 0)
|
||||||
|
|
||||||
|
LIST (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/backbone)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY (src)
|
||||||
|
ADD_SUBDIRECTORY (po)
|
||||||
|
ADD_SUBDIRECTORY (pkg-config)
|
||||||
|
ADD_SUBDIRECTORY (test)
|
||||||
|
ADD_SUBDIRECTORY (cpack)
|
||||||
|
|
||||||
|
# enable testing
|
||||||
|
#ENABLE_TESTING ()
|
|
@ -0,0 +1,165 @@
|
||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
|
@ -0,0 +1,84 @@
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
Build-Time Dependencies
|
||||||
|
|
||||||
|
Vala: https://wiki.gnome.org/Projects/Vala
|
||||||
|
Gee: https://wiki.gnome.org/Projects/Libgee
|
||||||
|
CMake: http://www.cmake.org
|
||||||
|
NSIS (W32): http://nsis.sourceforge.net
|
||||||
|
|
||||||
|
Run-Time Dependencies
|
||||||
|
|
||||||
|
Gee: https://wiki.gnome.org/Projects/Libgee
|
||||||
|
|
||||||
|
Operation Systems
|
||||||
|
|
||||||
|
* GNU/Linux (Gentoo, Debian, etc.)
|
||||||
|
* MS Windows (Windows 5.1 aka XP)
|
||||||
|
* BSD-based (FreeBSD, OpenBSD, NetBSD, Mac OS X)
|
||||||
|
|
||||||
|
If you need support of one more OS, be free in writing of patches and sending
|
||||||
|
pull-requests to the mainstream.
|
||||||
|
|
||||||
|
|
||||||
|
Compilation
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Compilation under GNU/Linux
|
||||||
|
|
||||||
|
$ mkdir build-gcc && cd build-gcc
|
||||||
|
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
|
$ make -j$((`getconf _NPROCESSORS_ONLN`+1))
|
||||||
|
|
||||||
|
Compilation under MS Windows
|
||||||
|
|
||||||
|
$ mkdir build-mingw && cd build-mingw
|
||||||
|
$ cmake -G "MSYS Makefiles" .. -DCMAKE_BUILD_TYPE=Release
|
||||||
|
$ make -j$((NUMBER_OF_PROCESSORS + 1))
|
||||||
|
|
||||||
|
Compilation under BSD-based Systems.
|
||||||
|
|
||||||
|
TODO: add description here.
|
||||||
|
|
||||||
|
|
||||||
|
Packing/Installation
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Packing/Installation under GNU/Linux
|
||||||
|
|
||||||
|
$ cpack
|
||||||
|
Install using System Package Manager.
|
||||||
|
|
||||||
|
Packing/Installation under MS Windows
|
||||||
|
|
||||||
|
$ cpack
|
||||||
|
Install using generated by NSIS executable.
|
||||||
|
|
||||||
|
Packing/Installation under BSD-based
|
||||||
|
|
||||||
|
$ cpack
|
||||||
|
Install using System Package Manager.
|
||||||
|
|
||||||
|
|
||||||
|
Testing
|
||||||
|
-------
|
||||||
|
|
||||||
|
Testing under GNU/Linux
|
||||||
|
|
||||||
|
$ ctest -j$((`getconf _NPROCESSORS_ONLN`+1))
|
||||||
|
|
||||||
|
Automated tests for memory leaks:
|
||||||
|
$ ctest -j$((NUMBER_OF_PROCESSORS + 1)) -D NightlyMemCheck && grep definitely Testing/Temporary/LastDynamicAnalysis_*.log
|
||||||
|
|
||||||
|
Testing under MS Windows
|
||||||
|
|
||||||
|
$ ctest -j$((NUMBER_OF_PROCESSORS + 1))
|
||||||
|
Automated tests for memory leaks are not available as far as Valgrind not
|
||||||
|
present on this platform.
|
||||||
|
|
||||||
|
Testing under BSD-based
|
||||||
|
|
||||||
|
$ ctest
|
||||||
|
Automated tests for memory leaks are not available as far as Valgrind not
|
||||||
|
present on this platform.
|
|
@ -0,0 +1,2 @@
|
||||||
|
Kolan Sh
|
||||||
|
email: backbone@backbone.ws
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Cairo-Chart (GTK3+)
|
||||||
|
|
||||||
|
Gtk+ Chart for DrawingArea widget with multiaxes, dates and cursors.
|
||||||
|
|
||||||
|
Project Page: https://redmine.backbone.ws/projects/cairo-chart
|
||||||
|
|
||||||
|
Git: https://git.backbone.ws/gtk/cairo-chart
|
||||||
|
|
||||||
|
## View YouTube movie
|
||||||
|
|
||||||
|
[![View video](https://img.youtube.com/vi/wmZAw2csjQg/0.jpg)](https://www.youtube.com/watch?v=wmZAw2csjQg)
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
![Screenshot1](https://redmine.backbone.ws/attachments/download/424/20171225_020441.png)
|
||||||
|
![Screenshot2](https://redmine.backbone.ws/attachments/download/425/20171225_020414.png)
|
||||||
|
![Screenshot3](https://redmine.backbone.ws/attachments/download/426/20171225_020350.png)
|
||||||
|
![Screenshot4](https://redmine.backbone.ws/attachments/download/427/20171225_020330.png)
|
||||||
|
![Screenshot5](https://redmine.backbone.ws/attachments/download/428/20171225_020315.png)
|
||||||
|
![Screenshot6](https://redmine.backbone.ws/attachments/download/429/20171225_020301.png)
|
||||||
|
![Screenshot7](https://redmine.backbone.ws/attachments/download/430/20171225_020237.png)
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 5aec8e830a52e88f61c8844ac15dca72b1ef7f06
|
|
@ -0,0 +1,10 @@
|
||||||
|
SET (CONTACT "backbone@backbone.ws")
|
||||||
|
SET (DEBIAN_DEPENDENCIES "valac (>= 0.24), libgtk-3-0 (>= 3.20)")
|
||||||
|
SET (DEBIAN_SECTION "Libraries")
|
||||||
|
SET (REDHAT_DEPENDENCIES "vala >= 0.24, gtk+ >= 3.20")
|
||||||
|
SET (REDHAT_SECTION "Development/Libraries")
|
||||||
|
SET (LICENSE "LGPLv3+")
|
||||||
|
SET (WIN32_UNINSTALL_NAME "GtkChart") # <= 8 symbols for the name
|
||||||
|
SET (CPACK_NSIS_MENU_LINKS "https://redmine.backbone.ws/projects/gtkchart"
|
||||||
|
"Homepage for GtkChart")
|
||||||
|
INCLUDE (CPackCommonRules)
|
|
@ -0,0 +1,13 @@
|
||||||
|
INCLUDE (PkgConfigCommonRules)
|
||||||
|
|
||||||
|
SET (PkgConfigLibs "-L\${libdir}")
|
||||||
|
IF (WIN32)
|
||||||
|
SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}-${MAJOR}")
|
||||||
|
ELSE (WIN32)
|
||||||
|
SET (PkgConfigLibs "${PkgConfigLibs} -l${PROJECT_LOWERCASE_NAME}.so.${MAJOR}")
|
||||||
|
ENDIF (WIN32)
|
||||||
|
|
||||||
|
CONFIGURE_FILE (
|
||||||
|
"${CMAKE_SOURCE_DIR}/cmake/backbone/templates/pkg-config.pc.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_LOWERCASE_NAME}-${MAJOR}.pc"
|
||||||
|
)
|
|
@ -0,0 +1 @@
|
||||||
|
INCLUDE (GettextCommonRules)
|
|
@ -0,0 +1 @@
|
||||||
|
INCLUDE (GettextLangRules)
|
|
@ -0,0 +1,101 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
// If one of axis:title or axis:min/max are different
|
||||||
|
// then draw separate axis for each/all series
|
||||||
|
// or specify series name near the axis
|
||||||
|
public class Axis {
|
||||||
|
Float128 _min = 0;
|
||||||
|
Float128 _max = 0;
|
||||||
|
public Float128 min {
|
||||||
|
get { return _min; }
|
||||||
|
set { _min = zoom_min = value; }
|
||||||
|
default = 0;
|
||||||
|
}
|
||||||
|
public Float128 max {
|
||||||
|
get { return _max; }
|
||||||
|
set { _max = zoom_max = value; }
|
||||||
|
default = 1;
|
||||||
|
}
|
||||||
|
public Float128 zoom_min = 0;
|
||||||
|
public Float128 zoom_max = 1;
|
||||||
|
public Text title = new Text ("");
|
||||||
|
public enum Type {
|
||||||
|
NUMBERS = 0,
|
||||||
|
DATE_TIME
|
||||||
|
}
|
||||||
|
public enum ScaleType {
|
||||||
|
LINEAR = 0, // default
|
||||||
|
// LOGARITHMIC, // TODO
|
||||||
|
// etc
|
||||||
|
}
|
||||||
|
public Type type;
|
||||||
|
public ScaleType scale_type;
|
||||||
|
public enum Position {
|
||||||
|
LOW = 0,
|
||||||
|
HIGH = 1,
|
||||||
|
BOTH = 2
|
||||||
|
}
|
||||||
|
public Position position = Position.LOW;
|
||||||
|
|
||||||
|
string _format = "%.2Lf";
|
||||||
|
string _date_format = "%Y.%m.%d";
|
||||||
|
string _time_format = "%H:%M:%S";
|
||||||
|
int _dsec_signs = 2; // 2 signs = centiseconds
|
||||||
|
public string format {
|
||||||
|
get { return _format; }
|
||||||
|
set {
|
||||||
|
// TODO: check format
|
||||||
|
_format = value;
|
||||||
|
}
|
||||||
|
default = "%.2Lf";
|
||||||
|
}
|
||||||
|
public string date_format {
|
||||||
|
get { return _date_format; }
|
||||||
|
set {
|
||||||
|
// TODO: check format
|
||||||
|
_date_format = value;
|
||||||
|
}
|
||||||
|
default = "%Y.%m.%d";
|
||||||
|
}
|
||||||
|
public string time_format {
|
||||||
|
get { return _time_format; }
|
||||||
|
set {
|
||||||
|
// TODO: check format
|
||||||
|
_time_format = value;
|
||||||
|
}
|
||||||
|
default = "%H:%M:%S";
|
||||||
|
}
|
||||||
|
public int dsec_signs {
|
||||||
|
get { return _dsec_signs; }
|
||||||
|
set {
|
||||||
|
// TODO: check format
|
||||||
|
_dsec_signs = value;
|
||||||
|
}
|
||||||
|
default = 2;
|
||||||
|
}
|
||||||
|
public FontStyle font_style = FontStyle ();
|
||||||
|
public Color color = Color ();
|
||||||
|
public LineStyle line_style = LineStyle ();
|
||||||
|
public double font_indent = 5;
|
||||||
|
|
||||||
|
public Axis copy () {
|
||||||
|
var axis = new Axis ();
|
||||||
|
axis._date_format = this._date_format;
|
||||||
|
axis._dsec_signs = this._dsec_signs;
|
||||||
|
axis._format = this._format;
|
||||||
|
axis._time_format = this._time_format;
|
||||||
|
axis.color = this.color;
|
||||||
|
axis.font_indent = this.font_indent;
|
||||||
|
axis.font_style = this.font_style;
|
||||||
|
axis.line_style = this.line_style;
|
||||||
|
axis.max = this.max;
|
||||||
|
axis.min = this.min;
|
||||||
|
axis.position = this.position;
|
||||||
|
axis.scale_type = this.scale_type;
|
||||||
|
axis.title = this.title.copy();
|
||||||
|
axis.type = this.type;
|
||||||
|
return axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Axis () {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
SET (LibName ${PROJECT_LOWERCASE_NAME})
|
||||||
|
FILE (GLOB_RECURSE LibSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala)
|
||||||
|
SET (LibPackages cairo gtk+-3.0)
|
||||||
|
SET (LibPkgModules gtk+-3.0)
|
||||||
|
SET (LibInstall ON)
|
||||||
|
SET (LibExtraSources ${CMAKE_CURRENT_BINARY_DIR}/library_constructor.c)
|
||||||
|
SET (LC_RELATIVE_PREFIX "..")
|
||||||
|
CONFIGURE_FILE ( "${CMAKE_SOURCE_DIR}/cmake/backbone/templates/library_constructor.c.in" "${LibExtraSources}")
|
||||||
|
INCLUDE_DIRECTORIES ("${CMAKE_SOURCE_DIR}/src")
|
||||||
|
SET (LibCustomVapis ${CMAKE_SOURCE_DIR}/src/cairo-chart-float128type.vapi)
|
||||||
|
INCLUDE (ValaLibCommonRules)
|
||||||
|
INSTALL (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cairo-chart-float128type.h DESTINATION include
|
||||||
|
RENAME cairo-chart-float128type-${MAJOR}.h)
|
||||||
|
INSTALL (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cairo-chart-float128type.vapi DESTINATION share/vala/vapi
|
||||||
|
RENAME cairo-chart-float128type-${MAJOR}.vapi)
|
||||||
|
CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/cairo-chart.deps.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/cairo-chart-${MAJOR}.deps)
|
||||||
|
INSTALL (FILES ${CMAKE_CURRENT_BINARY_DIR}/cairo-chart-${MAJOR}.deps DESTINATION share/vala/vapi)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public struct Color {
|
||||||
|
double red;
|
||||||
|
double green;
|
||||||
|
double blue;
|
||||||
|
double alpha;
|
||||||
|
|
||||||
|
public Color (double red = 0.0, double green = 0.0, double blue = 0.0, double alpha = 1.0) {
|
||||||
|
this.red = red; this.green = green; this.blue = blue; this.alpha = alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public enum FontOrient {
|
||||||
|
HORIZONTAL = 0,
|
||||||
|
VERTICAL
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct FontStyle {
|
||||||
|
string family;
|
||||||
|
Cairo.FontSlant slant;
|
||||||
|
Cairo.FontWeight weight;
|
||||||
|
|
||||||
|
FontOrient orientation;
|
||||||
|
double size;
|
||||||
|
|
||||||
|
public FontStyle (string family = "Sans",
|
||||||
|
Cairo.FontSlant slant = Cairo.FontSlant.NORMAL,
|
||||||
|
Cairo.FontWeight weight = Cairo.FontWeight.NORMAL,
|
||||||
|
double size = 10,
|
||||||
|
FontOrient orientation = FontOrient.HORIZONTAL) {
|
||||||
|
this.family = family;
|
||||||
|
this.slant = slant;
|
||||||
|
this.weight = weight;
|
||||||
|
this.size = size;
|
||||||
|
this.orientation = orientation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public class Grid {
|
||||||
|
/*public enum GridType {
|
||||||
|
PRICK_LINE = 0, // default
|
||||||
|
LINE
|
||||||
|
}*/
|
||||||
|
public Color color = Color (0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
public LineStyle line_style = LineStyle ();
|
||||||
|
|
||||||
|
public Grid copy () {
|
||||||
|
var grid = new Grid ();
|
||||||
|
grid.color = this.color;
|
||||||
|
grid.line_style = this.line_style;
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Grid () {
|
||||||
|
line_style.dashes = {2, 3};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public struct LabelStyle {
|
||||||
|
FontStyle font_style;
|
||||||
|
LineStyle frame_line_style;
|
||||||
|
Color bg_color;
|
||||||
|
Color frame_color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public class Legend {
|
||||||
|
public enum Position {
|
||||||
|
TOP = 0, // default
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
BOTTOM
|
||||||
|
}
|
||||||
|
public Position position = Position.TOP;
|
||||||
|
public FontStyle font_style = FontStyle();
|
||||||
|
public Color bg_color = Color(1, 1, 1);
|
||||||
|
public LineStyle border_style = LineStyle ();
|
||||||
|
public double indent = 5;
|
||||||
|
|
||||||
|
public Legend copy () {
|
||||||
|
var legend = new Legend ();
|
||||||
|
legend.position = this.position;
|
||||||
|
legend.font_style = this.font_style;
|
||||||
|
legend.bg_color = this.bg_color;
|
||||||
|
legend.indent = this.indent;
|
||||||
|
return legend;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Legend () {
|
||||||
|
border_style.color = Color (0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public struct LineStyle {
|
||||||
|
double width;
|
||||||
|
Cairo.LineJoin line_join;
|
||||||
|
Cairo.LineCap line_cap;
|
||||||
|
double[]? dashes;
|
||||||
|
double dash_offset;
|
||||||
|
Color color;
|
||||||
|
|
||||||
|
public LineStyle (Color color = Color(),
|
||||||
|
double width = 1,
|
||||||
|
double[]? dashes = null, double dash_offset = 0,
|
||||||
|
Cairo.LineJoin line_join = Cairo.LineJoin.MITER,
|
||||||
|
Cairo.LineCap line_cap = Cairo.LineCap.ROUND
|
||||||
|
) {
|
||||||
|
this.width = width;
|
||||||
|
this.line_join = line_join;
|
||||||
|
this.line_cap = line_cap;
|
||||||
|
this.dashes = dashes;
|
||||||
|
this.dash_offset = dash_offset;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public class Place {
|
||||||
|
double _x_low = 0;
|
||||||
|
double _x_high = 0;
|
||||||
|
double _y_low = 0;
|
||||||
|
double _y_high = 0;
|
||||||
|
public double x_low {
|
||||||
|
get { return _x_low; }
|
||||||
|
set { _x_low = zoom_x_low = value; }
|
||||||
|
default = 0;
|
||||||
|
}
|
||||||
|
public double x_high {
|
||||||
|
get { return _x_high; }
|
||||||
|
set { _x_high = zoom_x_high = value; }
|
||||||
|
default = 0;
|
||||||
|
}
|
||||||
|
public double y_low {
|
||||||
|
get { return _y_low; }
|
||||||
|
set { _y_low = zoom_y_low = value; }
|
||||||
|
default = 0;
|
||||||
|
}
|
||||||
|
public double y_high {
|
||||||
|
get { return _y_high; }
|
||||||
|
set { _y_high = zoom_y_high = value; }
|
||||||
|
default = 0;
|
||||||
|
}
|
||||||
|
public double zoom_x_low = 0;
|
||||||
|
public double zoom_x_high = 1;
|
||||||
|
public double zoom_y_low = 0;
|
||||||
|
public double zoom_y_high = 1;
|
||||||
|
|
||||||
|
public Place copy () {
|
||||||
|
var place = new Place ();
|
||||||
|
place.x_low = this.x_low;
|
||||||
|
place.x_high = this.x_high;
|
||||||
|
place.y_low = this.y_low;
|
||||||
|
place.y_high = this.y_high;
|
||||||
|
return place;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Place (double x_low = 0, double x_high = 1, double y_low = 0, double y_high = 1) {
|
||||||
|
this.x_low = x_low;
|
||||||
|
this.x_high = x_high;
|
||||||
|
this.y_low = y_low;
|
||||||
|
this.y_high = y_high;
|
||||||
|
zoom_x_low = x_low;
|
||||||
|
zoom_x_high = x_high;
|
||||||
|
zoom_y_low = y_low;
|
||||||
|
zoom_y_high = y_high;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
public struct Point {
|
||||||
|
Float128 x;
|
||||||
|
Float128 y;
|
||||||
|
|
||||||
|
public Point (Float128 x = 0.0, Float128 y = 0.0) {
|
||||||
|
this.x = x; this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
using Cairo;
|
||||||
|
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
|
||||||
|
public class Series {
|
||||||
|
|
||||||
|
public Point[] points = {};
|
||||||
|
public enum Sort {
|
||||||
|
BY_X = 0,
|
||||||
|
BY_Y = 1,
|
||||||
|
NO_SORT
|
||||||
|
}
|
||||||
|
public Sort sort = Sort.BY_X;
|
||||||
|
|
||||||
|
public Axis axis_x = new Axis();
|
||||||
|
public Axis axis_y = new Axis();
|
||||||
|
|
||||||
|
public enum MarkerType {
|
||||||
|
NONE = 0, // default
|
||||||
|
SQUARE,
|
||||||
|
CIRCLE,
|
||||||
|
TRIANGLE,
|
||||||
|
PRICLE_SQUARE,
|
||||||
|
PRICLE_CIRCLE,
|
||||||
|
PRICLE_TRIANGLE
|
||||||
|
}
|
||||||
|
|
||||||
|
public Place place = new Place();
|
||||||
|
public Text title = new Text ();
|
||||||
|
public MarkerType marker_type = MarkerType.SQUARE;
|
||||||
|
|
||||||
|
public Grid grid = new Grid ();
|
||||||
|
|
||||||
|
public LineStyle line_style = LineStyle ();
|
||||||
|
|
||||||
|
protected Color _color = Color (0.0, 0.0, 0.0, 1.0);
|
||||||
|
public Color color {
|
||||||
|
get { return _color; }
|
||||||
|
set {
|
||||||
|
_color = value;
|
||||||
|
line_style.color = _color;
|
||||||
|
axis_x.color = _color;
|
||||||
|
axis_y.color = _color;
|
||||||
|
grid.color = _color;
|
||||||
|
grid.color.alpha = 0.5;
|
||||||
|
grid.line_style.color = _color;
|
||||||
|
grid.line_style.color.alpha = 0.5;
|
||||||
|
}
|
||||||
|
default = Color (0.0, 0.0, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool zoom_show = true;
|
||||||
|
|
||||||
|
public Series copy () {
|
||||||
|
var series = new Series ();
|
||||||
|
series._color = this._color;
|
||||||
|
series.axis_x = this.axis_x.copy ();
|
||||||
|
series.axis_y = this.axis_y.copy ();
|
||||||
|
series.grid = this.grid.copy ();
|
||||||
|
series.line_style = this.line_style;
|
||||||
|
series.marker_type = this.marker_type;
|
||||||
|
series.place = this.place.copy();
|
||||||
|
series.points = this.points;
|
||||||
|
series.sort = this.sort;
|
||||||
|
series.title = this.title.copy();
|
||||||
|
series.zoom_show = this.zoom_show;
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Series () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
[Compact]
|
||||||
|
public class Text {
|
||||||
|
public string text = "";
|
||||||
|
public FontStyle style = FontStyle ();
|
||||||
|
public Color color = Color();
|
||||||
|
|
||||||
|
Cairo.TextExtents get_extents (Cairo.Context context) {
|
||||||
|
context.select_font_face (style.family,
|
||||||
|
style.slant,
|
||||||
|
style.weight);
|
||||||
|
context.set_font_size (style.size);
|
||||||
|
Cairo.TextExtents extents;
|
||||||
|
context.text_extents (text, out extents);
|
||||||
|
return extents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get_width (Cairo.Context context) {
|
||||||
|
var extents = get_extents (context);
|
||||||
|
if (style.orientation == FontOrient.HORIZONTAL)
|
||||||
|
return extents.width;
|
||||||
|
else
|
||||||
|
return extents.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get_height (Cairo.Context context) {
|
||||||
|
var extents = get_extents (context);
|
||||||
|
if (style.orientation == FontOrient.HORIZONTAL)
|
||||||
|
return extents.height;
|
||||||
|
else
|
||||||
|
return extents.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get_x_bearing (Cairo.Context context) {
|
||||||
|
var extents = get_extents (context);
|
||||||
|
if (style.orientation == FontOrient.HORIZONTAL)
|
||||||
|
return extents.x_bearing;
|
||||||
|
else
|
||||||
|
return extents.y_bearing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Text (string text = "",
|
||||||
|
FontStyle style = FontStyle(),
|
||||||
|
Color color = Color()) {
|
||||||
|
this.text = text;
|
||||||
|
this.style = style;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Text copy () {
|
||||||
|
var text = new Text ();
|
||||||
|
text.text = this.text;
|
||||||
|
text.style = this.style;
|
||||||
|
text.color = this.color;
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
typedef __float128 cairo_chart_float128;
|
||||||
|
typedef long double cairo_chart_long_double;
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Gtk.CairoChart {
|
||||||
|
[CCode (cname = "cairo_chart_float128", has_type_id = false, cheader_filename = "cairo-chart-float128type.h")]
|
||||||
|
public struct Float128 : double {}
|
||||||
|
[CCode (cname = "cairo_chart_long_double", has_type_id = false, cheader_filename = "cairo-chart-float128type.h")]
|
||||||
|
public struct LongDouble : double {}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
cairo-chart-float128type-@MAJOR@
|
|
@ -0,0 +1,8 @@
|
||||||
|
SET (BinName chart_test)
|
||||||
|
FILE (GLOB_RECURSE BinSources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ChartTest.vala)
|
||||||
|
SET (BinPackages gtk+-3.0)
|
||||||
|
SET (BinPkgModules gtk+-3.0)
|
||||||
|
SET (BinCustomVapis ${CMAKE_BINARY_DIR}/src/${PROJECT_LOWERCASE_NAME}-${MAJOR}.vapi ${CMAKE_SOURCE_DIR}/src/cairo-chart-float128type.vapi)
|
||||||
|
SET (BinLinkLibs ${PROJECT_LOWERCASE_NAME})
|
||||||
|
INCLUDE_DIRECTORIES ("${CMAKE_BINARY_DIR}/src;${CMAKE_SOURCE_DIR}/src")
|
||||||
|
INCLUDE (ValaBinCommonRules)
|
|
@ -0,0 +1,578 @@
|
||||||
|
using Gtk, CairoChart;
|
||||||
|
|
||||||
|
void plot_chart1 (Chart chart) {
|
||||||
|
var s1 = new Series ();
|
||||||
|
var s2 = new Series ();
|
||||||
|
var s3 = new Series ();
|
||||||
|
|
||||||
|
s1.title = new Text("Series 1"); s1.color = Color (1, 0, 0);
|
||||||
|
s1.points = {Point(0, 0), Point(2, 1), Point(1, 3)};
|
||||||
|
s1.axis_x.position = Axis.Position.HIGH;
|
||||||
|
s1.axis_x.format = "%.3Lf";
|
||||||
|
s2.title = new Text("Series 2"); s2.color = Color (0, 1, 0);
|
||||||
|
s2.points = {Point(5, -3), Point(25, -18), Point(-11, 173)};
|
||||||
|
s3.title = new Text("Series 3"); s3.color = Color (0, 0, 1);
|
||||||
|
s3.points = {Point(9, 17), Point(2, 10), Point(122, 31)};
|
||||||
|
s3.axis_y.position = Axis.Position.HIGH;
|
||||||
|
|
||||||
|
s1.axis_x.min = 0; s1.axis_x.max = 2;
|
||||||
|
s1.axis_y.min = 0; s1.axis_y.max = 3;
|
||||||
|
s1.place.x_low = 0.25; s1.place.x_high = 0.75;
|
||||||
|
s1.place.y_low = 0.3; s1.place.y_high = 0.9;
|
||||||
|
|
||||||
|
s2.axis_x.min = -15; s2.axis_x.max = 30;
|
||||||
|
s2.axis_y.min = -20; s2.axis_y.max = 200;
|
||||||
|
s2.place.x_low = 0.5; s2.place.x_high = 1;
|
||||||
|
s2.place.y_low = 0.0; s2.place.y_high = 0.5;
|
||||||
|
|
||||||
|
s3.axis_x.min = 0; s3.axis_x.max = 130;
|
||||||
|
s3.axis_y.min = 15; s3.axis_y.max = 35;
|
||||||
|
s3.place.x_low = 0; s3.place.x_high = 0.5;
|
||||||
|
s3.place.y_low = 0.5; s3.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s2.marker_type = Series.MarkerType.CIRCLE;
|
||||||
|
s3.marker_type = Series.MarkerType.PRICLE_TRIANGLE;
|
||||||
|
|
||||||
|
s1.axis_x.title = new Text("Series 1: Axis X.");
|
||||||
|
s1.axis_y.title = new Text("Series 1: Axis Y.");
|
||||||
|
s2.axis_x.title = new Text("Series 2: Axis X.");
|
||||||
|
s2.axis_y.title = new Text("Series 2: Axis Y.");
|
||||||
|
s3.axis_x.title = new Text("Series 3: Axis X.");
|
||||||
|
s3.axis_y.title = new Text("Series 3: Axis Y.");
|
||||||
|
|
||||||
|
chart.series = { s1, s2, s3 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void plot_chart2 (Chart chart) {
|
||||||
|
var s1 = new Series ();
|
||||||
|
var s2 = new Series ();
|
||||||
|
var s3 = new Series ();
|
||||||
|
|
||||||
|
s1.title = new Text("Series 1"); s1.color = Color (1, 0, 0);
|
||||||
|
s1.points = {Point(-12, 0), Point(2, 1), Point(20, 3)};
|
||||||
|
s2.axis_y.position = Axis.Position.HIGH;
|
||||||
|
s1.axis_x.format = "%.3Lf";
|
||||||
|
s2.title = new Text("Series 2"); s2.color = Color (0, 1, 0);
|
||||||
|
s2.points = {Point(5, -3), Point(25, -18), Point(-11, 173)};
|
||||||
|
s3.title = new Text("Series 3"); s3.color = Color (0, 0, 1);
|
||||||
|
s3.points = {Point(9, 17), Point(2, 10), Point(-15, 31)};
|
||||||
|
s3.axis_y.position = Axis.Position.HIGH;
|
||||||
|
|
||||||
|
s1.axis_x.min = -15; s1.axis_x.max = 30;
|
||||||
|
s1.axis_y.min = 0; s1.axis_y.max = 3;
|
||||||
|
s1.place.x_low = 0.0; s1.place.x_high = 1.0;
|
||||||
|
s1.place.y_low = 0.3; s1.place.y_high = 0.9;
|
||||||
|
|
||||||
|
s2.axis_x.min = -15; s2.axis_x.max = 30;
|
||||||
|
s2.axis_y.min = -20; s2.axis_y.max = 200;
|
||||||
|
s2.place.x_low = 0.0; s2.place.x_high = 1.0;
|
||||||
|
s2.place.y_low = 0.0; s2.place.y_high = 0.5;
|
||||||
|
|
||||||
|
s3.axis_x.min = -15; s3.axis_x.max = 30;
|
||||||
|
s3.axis_y.min = 15; s3.axis_y.max = 35;
|
||||||
|
s3.place.x_low = 0.0; s3.place.x_high = 1.0;
|
||||||
|
s3.place.y_low = 0.5; s3.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s1.marker_type = Series.MarkerType.PRICLE_CIRCLE;
|
||||||
|
s2.marker_type = Series.MarkerType.PRICLE_SQUARE;
|
||||||
|
|
||||||
|
s1.axis_x.title = new Text("All Series: Axis X.");
|
||||||
|
s1.axis_y.title = new Text("Series 1: Axis Y.");
|
||||||
|
s2.axis_x.title = new Text("All Series: Axis X.");
|
||||||
|
s2.axis_y.title = new Text("Series 2: Axis Y.");
|
||||||
|
s3.axis_x.title = new Text("All Series: Axis X.");
|
||||||
|
s3.axis_y.title = new Text("Series 3: Axis Y.");
|
||||||
|
|
||||||
|
//s1.axis_x.position = s2.axis_x.position = s3.axis_x.position = Axis.Position.HIGH;
|
||||||
|
//s1.axis_x.type = s2.axis_x.type = s3.axis_x.type = Axis.Type.DATE_TIME;
|
||||||
|
//s1.axis_x.max = s2.axis_x.max = s3.axis_x.max = 5*24*3600;
|
||||||
|
|
||||||
|
chart.series = { s1, s2, s3 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void plot_chart3 (Chart chart) {
|
||||||
|
var s1 = new Series ();
|
||||||
|
var s2 = new Series ();
|
||||||
|
var s3 = new Series ();
|
||||||
|
|
||||||
|
s1.title = new Text("Series 1"); s1.color = Color (1, 0, 0);
|
||||||
|
s1.points = {Point(0, 70), Point(2, 155), Point(1, -3)};
|
||||||
|
s1.axis_x.position = Axis.Position.HIGH;
|
||||||
|
s1.axis_y.position = Axis.Position.HIGH;
|
||||||
|
s1.axis_x.format = "%.3Lf";
|
||||||
|
s2.title = new Text("Series 2"); s2.color = Color (0, 1, 0);
|
||||||
|
s2.points = {Point(5, -3), Point(25, -18), Point(-11, 173)};
|
||||||
|
s2.axis_y.position = Axis.Position.HIGH;
|
||||||
|
s3.title = new Text("Series 3"); s3.color = Color (0, 0, 1);
|
||||||
|
s3.points = {Point(9, -17), Point(2, 10), Point(122, 31)};
|
||||||
|
s3.axis_y.position = Axis.Position.HIGH;
|
||||||
|
|
||||||
|
s1.axis_x.min = 0; s1.axis_x.max = 2;
|
||||||
|
s1.axis_y.min = -20; s1.axis_y.max = 200;
|
||||||
|
s1.place.x_low = 0.25; s1.place.x_high = 0.75;
|
||||||
|
s1.place.y_low = 0.0; s1.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s2.axis_x.min = -15; s2.axis_x.max = 30;
|
||||||
|
s2.axis_y.min = -20; s2.axis_y.max = 200;
|
||||||
|
s2.place.x_low = 0.5; s2.place.x_high = 1;
|
||||||
|
s2.place.y_low = 0.0; s2.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s3.axis_x.min = 0; s3.axis_x.max = 130;
|
||||||
|
s3.axis_y.min = -20; s3.axis_y.max = 200;
|
||||||
|
s3.place.x_low = 0; s3.place.x_high = 0.5;
|
||||||
|
s3.place.y_low = 0.0; s3.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s2.marker_type = Series.MarkerType.PRICLE_CIRCLE;
|
||||||
|
s3.marker_type = Series.MarkerType.TRIANGLE;
|
||||||
|
|
||||||
|
s1.axis_x.title = new Text("Series 1: Axis X.");
|
||||||
|
s1.axis_y.title = new Text("Series 1: Axis Y.");
|
||||||
|
s2.axis_x.title = new Text("Series 2: Axis X.");
|
||||||
|
s2.axis_y.title = new Text("Series 2: Axis Y.");
|
||||||
|
s3.axis_x.title = new Text("Series 3: Axis X.");
|
||||||
|
s3.axis_y.title = new Text("Series 3: Axis Y.");
|
||||||
|
|
||||||
|
//s1.axis_y.position = s2.axis_y.position = s3.axis_y.position = Axis.Position.LOW;
|
||||||
|
|
||||||
|
chart.series = { s1, s2, s3 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void plot_chart4 (Chart chart) {
|
||||||
|
var s1 = new Series ();
|
||||||
|
var s2 = new Series ();
|
||||||
|
var s3 = new Series ();
|
||||||
|
var s4 = new Series ();
|
||||||
|
|
||||||
|
s1.axis_x.type = Axis.Type.DATE_TIME;
|
||||||
|
s3.axis_x.type = Axis.Type.DATE_TIME;
|
||||||
|
s4.axis_x.type = Axis.Type.DATE_TIME;
|
||||||
|
s4.axis_x.dsec_signs = 5;
|
||||||
|
|
||||||
|
var now = new DateTime.now_local().to_unix();
|
||||||
|
var high = (uint64) (253000000000L);
|
||||||
|
|
||||||
|
s1.title = new Text("Series 1"); s1.color = Color (1, 0, 0);
|
||||||
|
s1.points = {Point(now, 70), Point(now - 100000, 155), Point(now + 100000, 30)};
|
||||||
|
s1.axis_x.position = Axis.Position.HIGH;
|
||||||
|
s1.axis_y.position = Axis.Position.HIGH;
|
||||||
|
s2.title = new Text("Series 2"); s2.color = Color (0, 1, 0);
|
||||||
|
s2.points = {Point(5, -3), Point(25, -18), Point(-11, 173)};
|
||||||
|
s2.axis_y.position = Axis.Position.HIGH;
|
||||||
|
s3.title = new Text("Series 3"); s3.color = Color (0, 0, 1);
|
||||||
|
s3.points = {Point(high - 2 + 0.73, -17), Point(high - 1 + 0.234, 10), Point(high + 1 + 0.411, 31)};
|
||||||
|
s3.axis_y.position = Axis.Position.HIGH;
|
||||||
|
s4.title = new Text("Series 4"); s4.color = Color (0.5, 0.3, 0.9);
|
||||||
|
s4.points = {Point(high + 0.005, -19.05), Point(high + 0.0051, 28), Point(high + 0.0052, 55), Point(high + 0.0053, 44)};
|
||||||
|
s4.axis_y.position = Axis.Position.HIGH;
|
||||||
|
|
||||||
|
s1.axis_x.min = now - 100000; s1.axis_x.max = now + 100000;
|
||||||
|
s1.axis_y.min = -20; s1.axis_y.max = 200;
|
||||||
|
s1.place.x_low = 0.25; s1.place.x_high = 0.75;
|
||||||
|
s1.place.y_low = 0.0; s1.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s2.axis_x.min = -15; s2.axis_x.max = 30;
|
||||||
|
s2.axis_y.min = -20; s2.axis_y.max = 200;
|
||||||
|
s2.place.x_low = 0.2; s2.place.x_high = 1;
|
||||||
|
s2.place.y_low = 0.0; s2.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s3.axis_x.min = high - 2; s3.axis_x.max = high + 1;
|
||||||
|
s3.axis_y.min = -20; s3.axis_y.max = 200;
|
||||||
|
s3.place.x_low = 0; s3.place.x_high = 0.8;
|
||||||
|
s3.place.y_low = 0.0; s3.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s4.axis_x.min = high + 0.0049; s4.axis_x.max = high + 0.0054;
|
||||||
|
s4.axis_y.min = -20; s4.axis_y.max = 200;
|
||||||
|
s4.place.x_low = 0.2; s4.place.x_high = 1.0;
|
||||||
|
s4.place.y_low = 0.0; s4.place.y_high = 1.0;
|
||||||
|
|
||||||
|
s2.marker_type = Series.MarkerType.PRICLE_CIRCLE;
|
||||||
|
s3.marker_type = Series.MarkerType.TRIANGLE;
|
||||||
|
s4.marker_type = Series.MarkerType.PRICLE_SQUARE;
|
||||||
|
|
||||||
|
s1.axis_x.title = new Text("Series 1: Axis X.");
|
||||||
|
s1.axis_y.title = new Text("Series 1: Axis Y.");
|
||||||
|
s2.axis_x.title = new Text("Series 2: Axis X.");
|
||||||
|
s2.axis_y.title = new Text("Series 2: Axis Y.");
|
||||||
|
s3.axis_x.title = new Text("Series 3: Axis X.");
|
||||||
|
s3.axis_y.title = new Text("Series 3: Axis Y.");
|
||||||
|
s4.axis_x.title = new Text("Series 4: Axis X.");
|
||||||
|
s4.axis_y.title = new Text("Series 4: Axis Y.");
|
||||||
|
|
||||||
|
chart.series = { s1, s2, s3, s4 };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool point_in_chart (Chart chart, double x, double y) {
|
||||||
|
if (x < chart.plot_area_x_min) return false;
|
||||||
|
if (x > chart.plot_area_x_max) return false;
|
||||||
|
if (y < chart.plot_area_y_min) return false;
|
||||||
|
if (y > chart.plot_area_y_max) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MouseState {
|
||||||
|
FREE = 0, // default
|
||||||
|
DRAW_SELECTION,
|
||||||
|
MOVING_CHART,
|
||||||
|
CURSOR_SELECTION
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (string[] args) {
|
||||||
|
init (ref args);
|
||||||
|
|
||||||
|
var window = new Window ();
|
||||||
|
window.title = "Chart Test.";
|
||||||
|
window.border_width = 5;
|
||||||
|
window.window_position = WindowPosition.CENTER;
|
||||||
|
window.set_default_size (640, 480);
|
||||||
|
window.destroy.connect (main_quit);
|
||||||
|
|
||||||
|
var chart1 = new Chart();
|
||||||
|
var chart2 = new Chart();
|
||||||
|
var chart3 = new Chart();
|
||||||
|
var chart4 = new Chart();
|
||||||
|
var label = new Label ("Chart Test!");
|
||||||
|
var button1 = new Button.with_label("Separate axes");
|
||||||
|
var button2 = new Button.with_label("Common X axes");
|
||||||
|
var button3 = new Button.with_label("Common Y axes");
|
||||||
|
var button4 = new Button.with_label("Dates/Times");
|
||||||
|
var button5 = new Button.with_label("rm Axis Titles");
|
||||||
|
var button6 = new Button.with_label("Dates only");
|
||||||
|
var button7 = new Button.with_label("Times only");
|
||||||
|
var button8 = new Button.with_label("Date+Time");
|
||||||
|
|
||||||
|
plot_chart1 (chart1);
|
||||||
|
plot_chart2 (chart2);
|
||||||
|
plot_chart3 (chart3);
|
||||||
|
plot_chart4 (chart4);
|
||||||
|
|
||||||
|
chart1.selection_style = LineStyle(Color(0.3, 0.3, 0.3, 0.7), 1);
|
||||||
|
|
||||||
|
var da = new DrawingArea();
|
||||||
|
da.set_events ( Gdk.EventMask.BUTTON_PRESS_MASK
|
||||||
|
|Gdk.EventMask.BUTTON_RELEASE_MASK
|
||||||
|
|Gdk.EventMask.POINTER_MOTION_MASK
|
||||||
|
);
|
||||||
|
|
||||||
|
var chart = chart1;
|
||||||
|
|
||||||
|
var radio_button1 = new RadioButton.with_label (null, "Top Legend");
|
||||||
|
var radio_button2 = new RadioButton.with_label (radio_button1.get_group(), "Right Legend");
|
||||||
|
var radio_button3 = new RadioButton.with_label_from_widget (radio_button1, "Left Legend");
|
||||||
|
var radio_button4 = new RadioButton.with_label_from_widget (radio_button1, "Bottom Legend");
|
||||||
|
var radio_button7 = new RadioButton.with_label (null, "Vertical Cursors");
|
||||||
|
var radio_button8 = new RadioButton.with_label_from_widget (radio_button7, "Horizontal Cursors");
|
||||||
|
|
||||||
|
button1.clicked.connect (() => {
|
||||||
|
chart = chart1; da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
switch (chart.legend.position) {
|
||||||
|
case Legend.Position.TOP: radio_button1.set_active(true); break;
|
||||||
|
case Legend.Position.RIGHT: radio_button2.set_active(true); break;
|
||||||
|
case Legend.Position.LEFT: radio_button3.set_active(true); break;
|
||||||
|
case Legend.Position.BOTTOM: radio_button4.set_active(true); break;
|
||||||
|
}
|
||||||
|
switch (chart.cursors_orientation) {
|
||||||
|
case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break;
|
||||||
|
case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
button2.clicked.connect (() => {
|
||||||
|
chart = chart2; da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
switch (chart.legend.position) {
|
||||||
|
case Legend.Position.TOP: radio_button1.set_active(true); break;
|
||||||
|
case Legend.Position.RIGHT: radio_button2.set_active(true); break;
|
||||||
|
case Legend.Position.LEFT: radio_button3.set_active(true); break;
|
||||||
|
case Legend.Position.BOTTOM: radio_button4.set_active(true); break;
|
||||||
|
}
|
||||||
|
switch (chart.cursors_orientation) {
|
||||||
|
case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break;
|
||||||
|
case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
button3.clicked.connect (() => {
|
||||||
|
chart = chart3; da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
switch (chart.legend.position) {
|
||||||
|
case Legend.Position.TOP: radio_button1.set_active(true); break;
|
||||||
|
case Legend.Position.RIGHT: radio_button2.set_active(true); break;
|
||||||
|
case Legend.Position.LEFT: radio_button3.set_active(true); break;
|
||||||
|
case Legend.Position.BOTTOM: radio_button4.set_active(true); break;
|
||||||
|
}
|
||||||
|
switch (chart.cursors_orientation) {
|
||||||
|
case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break;
|
||||||
|
case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
button4.clicked.connect (() => {
|
||||||
|
chart = chart4; da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
switch (chart.legend.position) {
|
||||||
|
case Legend.Position.TOP: radio_button1.set_active(true); break;
|
||||||
|
case Legend.Position.RIGHT: radio_button2.set_active(true); break;
|
||||||
|
case Legend.Position.LEFT: radio_button4.set_active(true); break;
|
||||||
|
case Legend.Position.BOTTOM: radio_button4.set_active(true); break;
|
||||||
|
}
|
||||||
|
switch (chart.cursors_orientation) {
|
||||||
|
case Chart.CursorOrientation.VERTICAL: radio_button7.set_active(true); break;
|
||||||
|
case Chart.CursorOrientation.HORIZONTAL: radio_button8.set_active(true); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
button5.clicked.connect (() => {
|
||||||
|
for (var i = 0; i < chart.series.length; ++i) {
|
||||||
|
var s = chart.series[i];
|
||||||
|
s.axis_x.title.text = "";
|
||||||
|
s.axis_y.title.text = "";
|
||||||
|
}
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
});
|
||||||
|
button6.clicked.connect (() => {
|
||||||
|
for (var i = 0; i < chart.series.length; ++i) {
|
||||||
|
var s = chart.series[i];
|
||||||
|
s.axis_x.date_format = "%Y.%m.%d";
|
||||||
|
s.axis_x.time_format = "";
|
||||||
|
}
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
});
|
||||||
|
|
||||||
|
button7.clicked.connect (() => {
|
||||||
|
for (var i = 0; i < chart.series.length; ++i) {
|
||||||
|
var s = chart.series[i];
|
||||||
|
s.axis_x.date_format = "";
|
||||||
|
s.axis_x.time_format = "%H:%M:%S";
|
||||||
|
}
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
});
|
||||||
|
|
||||||
|
button8.clicked.connect (() => {
|
||||||
|
for (var i = 0; i < chart.series.length; ++i) {
|
||||||
|
var s = chart.series[i];
|
||||||
|
s.axis_x.date_format = "%Y.%m.%d";
|
||||||
|
s.axis_x.time_format = "%H:%M:%S";
|
||||||
|
}
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
radio_button1.toggled.connect ((button) => {
|
||||||
|
if (button.get_active()) {
|
||||||
|
chart.legend.position = Legend.Position.TOP;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
radio_button2.toggled.connect ((button) => {
|
||||||
|
if (button.get_active()) {
|
||||||
|
chart.legend.position = Legend.Position.RIGHT;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
radio_button3.toggled.connect ((button) => {
|
||||||
|
if (button.get_active()) {
|
||||||
|
chart.legend.position = Legend.Position.LEFT;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
radio_button4.toggled.connect ((button) => {
|
||||||
|
if (button.get_active()) {
|
||||||
|
chart.legend.position = Legend.Position.BOTTOM;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* var radio_button5 = new RadioButton.with_label (null, "Labels");
|
||||||
|
var radio_button6 = new RadioButton.with_label_from_widget (radio_button5, "Cursors");
|
||||||
|
radio_button5.toggled.connect ((button) => {
|
||||||
|
// TODO: set labels
|
||||||
|
if (button.get_active()) {
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
radio_button6.toggled.connect ((button) => {
|
||||||
|
// TODO: set cursors
|
||||||
|
if (button.get_active()) {
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
radio_button7.toggled.connect ((button) => {
|
||||||
|
if (button.get_active()) {
|
||||||
|
chart.cursors_orientation = Chart.CursorOrientation.VERTICAL;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
radio_button8.toggled.connect ((button) => {
|
||||||
|
if (button.get_active()) {
|
||||||
|
chart.cursors_orientation = Chart.CursorOrientation.HORIZONTAL;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MouseState mouse_state = MouseState.FREE;
|
||||||
|
|
||||||
|
double sel_x0 = 0, sel_x1 = 0, sel_y0 = 0, sel_y1 = 0;
|
||||||
|
double mov_x0 = 0, mov_y0 = 0;
|
||||||
|
|
||||||
|
da.draw.connect((context) => {
|
||||||
|
chart.context = context;
|
||||||
|
chart.width = da.get_allocated_width();
|
||||||
|
chart.height = da.get_allocated_height();
|
||||||
|
chart.clear();
|
||||||
|
|
||||||
|
// user's pre draw operations here...
|
||||||
|
// ...
|
||||||
|
|
||||||
|
/*var ret = */chart.draw();
|
||||||
|
|
||||||
|
// user's post draw operations here...
|
||||||
|
if (mouse_state == MouseState.DRAW_SELECTION)
|
||||||
|
chart.draw_selection (sel_x0, sel_y0, sel_x1, sel_y1);
|
||||||
|
|
||||||
|
// show delta
|
||||||
|
var str = chart.get_cursors_delta_str();
|
||||||
|
if (str != "") {
|
||||||
|
var text = "Δ = " + str;
|
||||||
|
var text_t = new Text(text);
|
||||||
|
var w = text_t.get_width(context);
|
||||||
|
var h = text_t.get_height(context);
|
||||||
|
var x0 = chart.plot_area_x_max - w - 5;
|
||||||
|
var y0 = chart.plot_area_y_min + h + 5;
|
||||||
|
chart.set_source_rgba(chart.legend.bg_color);
|
||||||
|
context.rectangle (x0, y0 - h, w, h);
|
||||||
|
context.fill();
|
||||||
|
context.move_to (x0, y0);
|
||||||
|
chart.set_source_rgba(chart.common_axis_color);
|
||||||
|
context.show_text(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;//ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
da.button_press_event.connect((event) => {
|
||||||
|
if (!point_in_chart(chart, event.x, event.y)) return true;
|
||||||
|
|
||||||
|
switch (event.button) {
|
||||||
|
case 1: // start cursor position selection
|
||||||
|
if ((event.state & Gdk.ModifierType.SHIFT_MASK) != 0) { // remove cursor
|
||||||
|
chart.set_active_cursor (event.x, event.y, true);
|
||||||
|
chart.remove_active_cursor();
|
||||||
|
mouse_state = MouseState.FREE;
|
||||||
|
} else { // add cursor
|
||||||
|
chart.set_active_cursor (event.x, event.y);
|
||||||
|
mouse_state = MouseState.CURSOR_SELECTION;
|
||||||
|
}
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // start zoom area selection
|
||||||
|
sel_x0 = sel_x1 = event.x;
|
||||||
|
sel_y0 = sel_y1 = event.y;
|
||||||
|
mouse_state = MouseState.DRAW_SELECTION;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // start moving
|
||||||
|
mov_x0 = event.x;
|
||||||
|
mov_y0 = event.y;
|
||||||
|
mouse_state = MouseState.MOVING_CHART;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // return ret;
|
||||||
|
});
|
||||||
|
da.button_release_event.connect((event) => {
|
||||||
|
|
||||||
|
if (!point_in_chart(chart, event.x, event.y)) return true;
|
||||||
|
|
||||||
|
switch (event.button) {
|
||||||
|
case 1: // start cursor position selection
|
||||||
|
if ((event.state & Gdk.ModifierType.SHIFT_MASK) != 0) { // remove cursor
|
||||||
|
//chart.remove_active_cursor ();
|
||||||
|
//da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
//mouse_state = MouseState.FREE;
|
||||||
|
} else { // add cursor
|
||||||
|
chart.add_active_cursor ();
|
||||||
|
mouse_state = MouseState.FREE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
sel_x1 = event.x;
|
||||||
|
sel_y1 = event.y;
|
||||||
|
if (sel_x1 > sel_x0 && sel_y1 > sel_y0)
|
||||||
|
chart.zoom_in (sel_x0, sel_y0, sel_x1, sel_y1);
|
||||||
|
else
|
||||||
|
chart.zoom_out ();
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
mouse_state = MouseState.FREE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
mouse_state = MouseState.FREE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // return ret;
|
||||||
|
});
|
||||||
|
da.motion_notify_event.connect((event) => {
|
||||||
|
if (!point_in_chart(chart, event.x, event.y)) return true;
|
||||||
|
|
||||||
|
switch (mouse_state) {
|
||||||
|
case MouseState.DRAW_SELECTION:
|
||||||
|
sel_x1 = event.x;
|
||||||
|
sel_y1 = event.y;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MouseState.MOVING_CHART:
|
||||||
|
var delta_x = event.x - mov_x0, delta_y = event.y - mov_y0;
|
||||||
|
chart.move (delta_x, delta_y);
|
||||||
|
mov_x0 = event.x;
|
||||||
|
mov_y0 = event.y;
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MouseState.CURSOR_SELECTION:
|
||||||
|
chart.set_active_cursor (event.x, event.y);
|
||||||
|
da.queue_draw_area(0, 0, da.get_allocated_width(), da.get_allocated_height());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // return ret;
|
||||||
|
});
|
||||||
|
da.add_events(Gdk.EventMask.SCROLL_MASK);
|
||||||
|
da.scroll_event.connect((event) => {
|
||||||
|
|
||||||
|
//var ret = chart.scroll_notify_event(event);
|
||||||
|
|
||||||
|
return true; // return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
var vbox2 = new Box(Orientation.VERTICAL, 0);
|
||||||
|
vbox2.pack_start(button1, false, false, 0);
|
||||||
|
vbox2.pack_start(button2, false, false, 0);
|
||||||
|
vbox2.pack_start(button3, false, false, 0);
|
||||||
|
vbox2.pack_start(button4, false, false, 0);
|
||||||
|
vbox2.pack_start(button5, false, false, 0);
|
||||||
|
vbox2.pack_start(button6, false, false, 0);
|
||||||
|
vbox2.pack_start(button7, false, false, 0);
|
||||||
|
vbox2.pack_start(button8, false, false, 0);
|
||||||
|
vbox2.pack_start(radio_button1, false, false, 0);
|
||||||
|
vbox2.pack_start(radio_button2, false, false, 0);
|
||||||
|
vbox2.pack_start(radio_button3, false, false, 0);
|
||||||
|
vbox2.pack_start(radio_button4, false, false, 0);
|
||||||
|
//vbox2.pack_start(radio_button5, false, false, 0);
|
||||||
|
//vbox2.pack_start(radio_button6, false, false, 0);
|
||||||
|
vbox2.pack_start(radio_button7, false, false, 0);
|
||||||
|
vbox2.pack_start(radio_button8, false, false, 0);
|
||||||
|
|
||||||
|
var hbox = new Box(Orientation.HORIZONTAL, 0);
|
||||||
|
hbox.pack_start(da, true, true, 0);
|
||||||
|
hbox.pack_end(vbox2, false, false, 0);
|
||||||
|
|
||||||
|
var vbox = new Box(Orientation.VERTICAL, 0);
|
||||||
|
vbox.pack_start(label, false, false, 0);
|
||||||
|
vbox.pack_end(hbox, true, true, 0);
|
||||||
|
|
||||||
|
window.add(vbox);
|
||||||
|
|
||||||
|
window.show_all();
|
||||||
|
|
||||||
|
Gtk.main();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 11c998aca2aa1b787286b336e579e5a4e31f471a
|
|
@ -0,0 +1,2 @@
|
||||||
|
BASEDIR=src
|
||||||
|
PKGS=gtk+-3.0
|
Loading…
Reference in New Issue