Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
601e8186ca |
@ -12,8 +12,7 @@
|
|||||||
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
|
<booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/>
|
||||||
<stringAttribute key="M2_USER_SETTINGS" value=""/>
|
<stringAttribute key="M2_USER_SETTINGS" value=""/>
|
||||||
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
|
<booleanAttribute key="M2_WORKSPACE_RESOLUTION" value="true"/>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_CLASSPATH_ONLY_JAR" value="false"/>
|
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
|
||||||
|
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/AdoptOpenJDK 8 [1.8.0_232]"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
|
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${project_loc:com.minres.scviewer.parent}"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
|
61
README.md
@ -18,55 +18,14 @@ The viewer has the following features
|
|||||||
- sqlite based
|
- sqlite based
|
||||||
- visualization of transaction relations
|
- visualization of transaction relations
|
||||||
|
|
||||||
To build the plugins the Eclipse SDK or PDE can be used.
|
To build the plugins the Eclipse SDK or PDE can be used. In both cases the Groovy
|
||||||
|
eclipse plugin (http://groovy.codehaus.org/Eclipse+Plugin or Market) has to be
|
||||||
Key Shortcuts
|
installed.
|
||||||
=============
|
|
||||||
|
|
||||||
Legend:
|
|
||||||
|
|
||||||
* Left Mouse Button: LMB
|
|
||||||
* Middle Mouse Button: MMB
|
|
||||||
* Mouse Scroll wheel: MScrl
|
|
||||||
* Context any means Name List, Value List or Waveform
|
|
||||||
|
|
||||||
| Input | Modifier | Context | Action |
|
|
||||||
|------------|----------|----------|-----------------------------------|
|
|
||||||
| LMB click | | any | select |
|
|
||||||
| LMB click | Shift | Waveform | move selected marker to position |
|
|
||||||
| LMB click | Control | Waveform | move cursor to position |
|
|
||||||
| LMB drag | | Waveform | zoom to range |
|
|
||||||
| MMB click | | Waveform | move selected marker to position |
|
|
||||||
| MScrl | | any | scroll window up/down |
|
|
||||||
| MScrl | Shift | any | scroll window left/right |
|
|
||||||
| MScrl | Control | Waveform | zoom in/out |
|
|
||||||
| Key left | | Waveform | scroll window to the left (slow) |
|
|
||||||
| Key right | | Waveform | scroll window to the right (slow) |
|
|
||||||
| Key left | Shift | Waveform | scroll window to the left (fast) |
|
|
||||||
| Key right | Shift | Waveform | scroll window to the right (fast) |
|
|
||||||
| Key up | | Waveform | move selection up |
|
|
||||||
| Key down | | Waveform | move selection down |
|
|
||||||
| Key up | Control | Waveform | move selected track up |
|
|
||||||
| Key down | Control | Waveform | move selected track down |
|
|
||||||
| Key + | Control | Waveform | zoom in |
|
|
||||||
| Key - | Control | Waveform | zoom out |
|
|
||||||
| Key Pos1 | | Waveform | jump to selected marker |
|
|
||||||
| Key End | | Waveform | jump to cursor |
|
|
||||||
| Key Del | | any | delete selected entries |
|
|
||||||
| LMB click | | ZoomBar | increment/decrement 1 page |
|
|
||||||
| LMB drag | | ZoomBar | drag both markers (pan) |
|
|
||||||
| LMB drag | Control | ZoomBar | drag one marker (zoom) |
|
|
||||||
| MMB drag | | ZoomBar | drag one marker (zoom) |
|
|
||||||
| xMB dclick | | ZoomBar | pan to position |
|
|
||||||
| MScrl | | ZoomBar | scroll window left/right |
|
|
||||||
| MScrl | Shift | ZoomBar | scroll window left/right double speed |
|
|
||||||
| MScrl | Control | ZoomBar | zoom in/out |
|
|
||||||
| Key left | | ZoomBar | scroll window to the left (slow) |
|
|
||||||
| Key right | | ZoomBar | scroll window to the right (slow) |
|
|
||||||
| Key up | | ZoomBar | scroll window to the left (slow) |
|
|
||||||
| Key down | | ZoomBar | scroll window to the right (slow) |
|
|
||||||
| Key PgUp | | ZoomBar | scroll window to the left (fast) |
|
|
||||||
| Key PgDown | | ZoomBar | scroll window to the right (fast) |
|
|
||||||
| Key Pos1 | | ZoomBar | scroll to begin |
|
|
||||||
| Key End | | ZoomBar | scroll to end |
|
|
||||||
|
|
||||||
|
TODO
|
||||||
|
====
|
||||||
|
- add more tests
|
||||||
|
- move to feature based product to allow automatic updates
|
||||||
|
- improve graphics
|
||||||
|
- catch-up e3 plugin to functionality of e4 product
|
||||||
|
- add calculated traces
|
||||||
|
1
doc/com.minres.scviewer.doc/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
/target/
|
|
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>com.minres.scviewer.doc</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
@ -1,168 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>com.minres.scviewer.doc</artifactId>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
<packaging>pom</packaging>
|
|
||||||
<parent>
|
|
||||||
<groupId>com.minres.scviewer</groupId>
|
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
|
||||||
<version>2.16.1</version>
|
|
||||||
<relativePath>../..</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
|
||||||
<asciidoctor.maven.plugin.version>2.0.0</asciidoctor.maven.plugin.version>
|
|
||||||
<asciidoctorj.pdf.version>1.6.2</asciidoctorj.pdf.version>
|
|
||||||
<help.plugin.target.dir>../../plugins/com.minres.scviewer.e4.application.help</help.plugin.target.dir>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.asciidoctor</groupId>
|
|
||||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
|
||||||
<version>${asciidoctor.maven.plugin.version}</version>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.asciidoctor</groupId>
|
|
||||||
<artifactId>asciidoctorj-pdf</artifactId>
|
|
||||||
<version>${asciidoctorj.pdf.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<configuration>
|
|
||||||
<sourceDirectory>src/asciidoc</sourceDirectory>
|
|
||||||
<sourceDocumentName>SCViewerHelp.adoc</sourceDocumentName>
|
|
||||||
<headerFooter>true</headerFooter>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>output-html</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>process-asciidoc</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<sourceHighlighter>coderay</sourceHighlighter>
|
|
||||||
<backend>html</backend>
|
|
||||||
<attributes>
|
|
||||||
<toc />
|
|
||||||
<linkcss>false</linkcss>
|
|
||||||
</attributes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>output-docbook</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>process-asciidoc</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<backend>docbook</backend>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>output-pdf</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>process-asciidoc</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<backend>pdf</backend>
|
|
||||||
<sourceHighlighter>coderay</sourceHighlighter>
|
|
||||||
<attributes>
|
|
||||||
<icons>font</icons>
|
|
||||||
<pagenums />
|
|
||||||
<toc />
|
|
||||||
<idprefix />
|
|
||||||
<idseparator>-</idseparator>
|
|
||||||
</attributes>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<version>2.6</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy-asciidoc-resources</id>
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-resources</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>target/generated-docs/</directory>
|
|
||||||
<includes>
|
|
||||||
<include>SCViewerHelp.xml</include>
|
|
||||||
<include>**/*.jpg</include>
|
|
||||||
<include>**/*.png</include>
|
|
||||||
<include>**/*.svg</include>
|
|
||||||
</includes>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
<outputDirectory>src/docbkx</outputDirectory>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>com.agilejava.docbkx</groupId>
|
|
||||||
<artifactId>docbkx-maven-plugin</artifactId>
|
|
||||||
<version>2.0.17</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<!-- <phase>generate-sources</phase> -->
|
|
||||||
<phase>generate-resources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>generate-eclipse</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.docbook</groupId>
|
|
||||||
<artifactId>docbook-xml</artifactId>
|
|
||||||
<version>4.4</version>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<configuration>
|
|
||||||
<sourceDirectory>src/docbkx</sourceDirectory>
|
|
||||||
<targetDirectory>${help.plugin.target.dir}</targetDirectory>
|
|
||||||
<preProcess>
|
|
||||||
<copy todir="${help.plugin.target.dir}/images">
|
|
||||||
<fileset dir="src/docbkx/images" />
|
|
||||||
</copy>
|
|
||||||
<copy todir="${help.plugin.target.dir}/css">
|
|
||||||
<fileset dir="src/docbkx/css" />
|
|
||||||
</copy>
|
|
||||||
</preProcess>
|
|
||||||
<imgSrcPath>./</imgSrcPath>
|
|
||||||
|
|
||||||
<useExtensions>1</useExtensions>
|
|
||||||
<highlightSource>1</highlightSource>
|
|
||||||
<highlightDefaultLanguage>java</highlightDefaultLanguage>
|
|
||||||
<calloutsExtension>1</calloutsExtension>
|
|
||||||
<paperType>A4</paperType>
|
|
||||||
<!--<fop1Extensions>1</fop1Extensions>
|
|
||||||
<foCustomization>${basedir}/conf/customization-fopdf.xsl</foCustomization>-->
|
|
||||||
|
|
||||||
<!-- This copies content (images, etc) for the HTML version -->
|
|
||||||
<!-- Any parameters specific to HTML version go here -->
|
|
||||||
<htmlStylesheet>css/narrow_style.css</htmlStylesheet>
|
|
||||||
<!-- <includes>titlepage/titlepage.templates.xml</includes> -->
|
|
||||||
<includes>SCViewerHelp.xml</includes>
|
|
||||||
<chunkedOutput>true</chunkedOutput>
|
|
||||||
<xincludeSupported>true</xincludeSupported>
|
|
||||||
<!-- <foCustomization>src/test/resources/docbook-fo.xsl</foCustomization> -->
|
|
||||||
<eclipsePluginId>com.minres.scviewer.e4.application.help</eclipsePluginId>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</project>
|
|
@ -1,25 +0,0 @@
|
|||||||
[#_introduction]
|
|
||||||
== Introduction
|
|
||||||
|
|
||||||
[#_overview]
|
|
||||||
=== SCViewer overview
|
|
||||||
|
|
||||||
SCViewer is composed of a set of eclipse plugins to display VCD and transaction streams
|
|
||||||
created by the SystemC VCD trace implementation and the SystemC Verification Library (SCV).
|
|
||||||
For further description of the SCV please refer to
|
|
||||||
http://www.accellera.org/activities/committees/systemc-verification.
|
|
||||||
|
|
||||||
|
|
||||||
[#_features]
|
|
||||||
=== SCViewer features
|
|
||||||
|
|
||||||
Features include:
|
|
||||||
|
|
||||||
* support of VCD files (compressed and uncompressed)
|
|
||||||
** real numbers
|
|
||||||
** showing vectors and real numbers as analog (step-wise & continuous)
|
|
||||||
* various value representations of bit vectors
|
|
||||||
* support of SCV transaction recordings in various formats
|
|
||||||
** text log files (compressed and uncompressed)
|
|
||||||
** sqlite based
|
|
||||||
** visualization of transaction relations
|
|
@ -1,55 +0,0 @@
|
|||||||
[#_reference]
|
|
||||||
== Reference
|
|
||||||
|
|
||||||
In this section you will find detailed descriptions of all GUI and menu elements of the SCViewer including their functions and keyboard shortcuts.
|
|
||||||
|
|
||||||
[#_keybindings]
|
|
||||||
=== Key Shortcuts
|
|
||||||
|
|
||||||
Legend:
|
|
||||||
|
|
||||||
* Left Mouse Button: LMB
|
|
||||||
* Middle Mouse Button: MMB
|
|
||||||
* Mouse Scroll wheel: MScrl
|
|
||||||
* Context any means Name List, Value List or Waveform
|
|
||||||
|
|
||||||
[cols="1,1,1,4",options="header"]
|
|
||||||
|===
|
|
||||||
| Input | Modifier | Context | Action
|
|
||||||
| LMB click | | any | select
|
|
||||||
| LMB click | Shift | Waveform | move selected marker to position
|
|
||||||
| LMB click | Control | Waveform | move cursor to position
|
|
||||||
| LMB drag | | Waveform | zoom to range
|
|
||||||
| MMB click | | Waveform | move selected marker to position
|
|
||||||
| MScrl | | any | scroll window up/down
|
|
||||||
| MScrl | Shift | any | scroll window left/right
|
|
||||||
| Key left | | Waveform | scroll window to the left (slow)
|
|
||||||
| Key right | | Waveform | scroll window to the right (slow)
|
|
||||||
| Key left | Shift | Waveform | scroll window to the left (fast)
|
|
||||||
| Key right | Shift | Waveform | scroll window to the right (fast)
|
|
||||||
| Key up | | Waveform | move selection up
|
|
||||||
| Key down | | Waveform | move selection down
|
|
||||||
| Key up | Control | Waveform | move selected track up
|
|
||||||
| Key down | Control | Waveform | move selected track down
|
|
||||||
| Key + | Control | Waveform | zoom in
|
|
||||||
| Key - | Control | Waveform | zoom out
|
|
||||||
| Key Pos1 | | Waveform | jump to selected marker
|
|
||||||
| Key End | | Waveform | jump to cursor
|
|
||||||
| Key Del | | any | delete selected entries
|
|
||||||
| LMB click | | ZoomBar | increment/decrement 1 page
|
|
||||||
| LMB drag | | ZoomBar | drag both markers (pan)
|
|
||||||
| LMB drag | Control | ZoomBar | drag one marker (zoom)
|
|
||||||
| MMB drag | | ZoomBar | drag one marker (zoom)
|
|
||||||
| xMB dclick | | ZoomBar | pan to position
|
|
||||||
| MScrl | | ZoomBar | scroll window left/right
|
|
||||||
| MScrl | Shift | ZoomBar | scroll window left/right double speed
|
|
||||||
| MScrl | Control | ZoomBar | zoom in/out
|
|
||||||
| Key left | | ZoomBar | scroll window to the left (slow)
|
|
||||||
| Key right | | ZoomBar | scroll window to the right (slow)
|
|
||||||
| Key up | | ZoomBar | scroll window to the left (slow)
|
|
||||||
| Key down | | ZoomBar | scroll window to the right (slow)
|
|
||||||
| Key PgUp | | ZoomBar | scroll window to the left (fast)
|
|
||||||
| Key PgDown | | ZoomBar | scroll window to the right (fast)
|
|
||||||
| Key Pos1 | | ZoomBar | scroll to begin
|
|
||||||
| Key End | | ZoomBar | scroll to end
|
|
||||||
|===
|
|
@ -1,39 +0,0 @@
|
|||||||
[#_start]
|
|
||||||
= SCViewer User Guide
|
|
||||||
:title-logo-image: image:Minres_logo_docs.png[width=750, align="right"]
|
|
||||||
:doctype: book
|
|
||||||
:source-highlighter: coderay
|
|
||||||
:coderay-linenums-mode: inline
|
|
||||||
:coderay-css: class
|
|
||||||
:listing-caption: Listing
|
|
||||||
:icons: font
|
|
||||||
//add table-of-contents (toc) and set its depth
|
|
||||||
:toc:
|
|
||||||
:toclevels: 3
|
|
||||||
:data-uri:
|
|
||||||
:sectnums:
|
|
||||||
:toc-title: Contents
|
|
||||||
:homepage: https://www.minres.com/
|
|
||||||
:keywords:
|
|
||||||
:title-page:
|
|
||||||
:xrefstyle: short
|
|
||||||
:table-caption: Table
|
|
||||||
:figure-caption: Figure
|
|
||||||
:appendix-caption: Appendix
|
|
||||||
:section-refsig: Chapter
|
|
||||||
//set directories
|
|
||||||
:imagesdir: ./images
|
|
||||||
:iconsdir: ./icons
|
|
||||||
:stylesdir: ./styles
|
|
||||||
:scriptsdir: ./js
|
|
||||||
:pdf-themesdir: ./themes
|
|
||||||
:pdf-theme: mnrs-doc
|
|
||||||
:pdf-fontsdir: ./fonts
|
|
||||||
|
|
||||||
|
|
||||||
// unset toc, otherwise it appears in table cells -> known bug, should be fixed in later versions!
|
|
||||||
:toc!:
|
|
||||||
|
|
||||||
include::Overview.adoc[]
|
|
||||||
|
|
||||||
include::Reference.adoc[]
|
|
@ -1,93 +0,0 @@
|
|||||||
Copyright (c) 2009-2011 by Accademia di Belle Arti di Urbino and students of MA course of Visual design. Some rights reserved.
|
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
||||||
This license is copied below, and is also available with a FAQ at:
|
|
||||||
http://scripts.sil.org/OFL
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------------------------------------------
|
|
||||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
||||||
-----------------------------------------------------------
|
|
||||||
|
|
||||||
PREAMBLE
|
|
||||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
||||||
development of collaborative font projects, to support the font creation
|
|
||||||
efforts of academic and linguistic communities, and to provide a free and
|
|
||||||
open framework in which fonts may be shared and improved in partnership
|
|
||||||
with others.
|
|
||||||
|
|
||||||
The OFL allows the licensed fonts to be used, studied, modified and
|
|
||||||
redistributed freely as long as they are not sold by themselves. The
|
|
||||||
fonts, including any derivative works, can be bundled, embedded,
|
|
||||||
redistributed and/or sold with any software provided that any reserved
|
|
||||||
names are not used by derivative works. The fonts and derivatives,
|
|
||||||
however, cannot be released under any other type of license. The
|
|
||||||
requirement for fonts to remain under this license does not apply
|
|
||||||
to any document created using the fonts or their derivatives.
|
|
||||||
|
|
||||||
DEFINITIONS
|
|
||||||
"Font Software" refers to the set of files released by the Copyright
|
|
||||||
Holder(s) under this license and clearly marked as such. This may
|
|
||||||
include source files, build scripts and documentation.
|
|
||||||
|
|
||||||
"Reserved Font Name" refers to any names specified as such after the
|
|
||||||
copyright statement(s).
|
|
||||||
|
|
||||||
"Original Version" refers to the collection of Font Software components as
|
|
||||||
distributed by the Copyright Holder(s).
|
|
||||||
|
|
||||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
||||||
or substituting -- in part or in whole -- any of the components of the
|
|
||||||
Original Version, by changing formats or by porting the Font Software to a
|
|
||||||
new environment.
|
|
||||||
|
|
||||||
"Author" refers to any designer, engineer, programmer, technical
|
|
||||||
writer or other person who contributed to the Font Software.
|
|
||||||
|
|
||||||
PERMISSION & CONDITIONS
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
||||||
redistribute, and sell modified and unmodified copies of the Font
|
|
||||||
Software, subject to the following conditions:
|
|
||||||
|
|
||||||
1) Neither the Font Software nor any of its individual components,
|
|
||||||
in Original or Modified Versions, may be sold by itself.
|
|
||||||
|
|
||||||
2) Original or Modified Versions of the Font Software may be bundled,
|
|
||||||
redistributed and/or sold with any software, provided that each copy
|
|
||||||
contains the above copyright notice and this license. These can be
|
|
||||||
included either as stand-alone text files, human-readable headers or
|
|
||||||
in the appropriate machine-readable metadata fields within text or
|
|
||||||
binary files as long as those fields can be easily viewed by the user.
|
|
||||||
|
|
||||||
3) No Modified Version of the Font Software may use the Reserved Font
|
|
||||||
Name(s) unless explicit written permission is granted by the corresponding
|
|
||||||
Copyright Holder. This restriction only applies to the primary font name as
|
|
||||||
presented to the users.
|
|
||||||
|
|
||||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
||||||
Software shall not be used to promote, endorse or advertise any
|
|
||||||
Modified Version, except to acknowledge the contribution(s) of the
|
|
||||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
||||||
permission.
|
|
||||||
|
|
||||||
5) The Font Software, modified or unmodified, in part or in whole,
|
|
||||||
must be distributed entirely under this license, and must not be
|
|
||||||
distributed under any other license. The requirement for fonts to
|
|
||||||
remain under this license does not apply to any document created
|
|
||||||
using the Font Software.
|
|
||||||
|
|
||||||
TERMINATION
|
|
||||||
This license becomes null and void if any of the above conditions are
|
|
||||||
not met.
|
|
||||||
|
|
||||||
DISCLAIMER
|
|
||||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
||||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
||||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
||||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
||||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 21 KiB |
@ -1,55 +0,0 @@
|
|||||||
page:
|
|
||||||
layout: portrait
|
|
||||||
margin: [2.3cm, 2cm, 2cm, 2.2cm]
|
|
||||||
size: A4
|
|
||||||
base:
|
|
||||||
font-color: #000000
|
|
||||||
font-color-mnrs-grey: #6a747c
|
|
||||||
font-color-mnrs-blue: #197788
|
|
||||||
font-family: titillium
|
|
||||||
font-size: 12
|
|
||||||
line-height-length: 16
|
|
||||||
line-height: $base-line-height-length / $base-font-size
|
|
||||||
align: justify
|
|
||||||
vertical-spacing: $base-line-height-length
|
|
||||||
heading:
|
|
||||||
font-color: $base-font-color-mnrs-grey
|
|
||||||
font-size: $base-font-size * 1.25
|
|
||||||
font-style: bold
|
|
||||||
line-height: $base-line-height * 1.2
|
|
||||||
margin-bottom: $vertical-spacing
|
|
||||||
link:
|
|
||||||
font-color: $base_font-color-mnrs-blue
|
|
||||||
outline-list:
|
|
||||||
indent: $base-font-size * 1.5
|
|
||||||
footer:
|
|
||||||
height: $base-line-height-length * 3.0
|
|
||||||
font-color: $base-font-color-mnrs-grey
|
|
||||||
font-size: $base-font-size * 0.9
|
|
||||||
line-height: 1
|
|
||||||
recto:
|
|
||||||
left:
|
|
||||||
content: '{description} v{revision}, © 2021 MINRES'
|
|
||||||
right:
|
|
||||||
content: '{page-number}'
|
|
||||||
verso:
|
|
||||||
left:
|
|
||||||
content: $footer_recto_right_content
|
|
||||||
right:
|
|
||||||
content: $footer_recto_left_content
|
|
||||||
table:
|
|
||||||
border_color: $base-font-color
|
|
||||||
border_width: 0.1
|
|
||||||
title-page:
|
|
||||||
align: right
|
|
||||||
font-color: $base-font-color-mnrs-grey
|
|
||||||
font-size: $base-font-size * 1.80
|
|
||||||
font-style: bold
|
|
||||||
font:
|
|
||||||
fallbacks: titilliumtext22l002-webfont.ttf
|
|
||||||
catalog:
|
|
||||||
titillium:
|
|
||||||
normal: titilliumtext22l002-webfont.ttf
|
|
||||||
bold: titilliumtext22l005-webfont.ttf
|
|
||||||
italic: TitilliumWeb-Italic.ttf
|
|
||||||
bold_italic: TitilliumWeb-BoldItalic.ttf
|
|
@ -1 +0,0 @@
|
|||||||
/SCViewerHelp.xml
|
|
@ -1,124 +0,0 @@
|
|||||||
P.Code {
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
text-indent: 0.00pt;
|
|
||||||
margin-top: 0.000000pt;
|
|
||||||
margin-bottom: 0.000000pt;
|
|
||||||
margin-right: 0.000000pt;
|
|
||||||
margin-left: 1.5em;
|
|
||||||
font-size: 100%;
|
|
||||||
font-weight: medium;
|
|
||||||
font-style: Regular;
|
|
||||||
color: #4444CC;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
font-family: "Courier New";
|
|
||||||
}
|
|
||||||
H6.CaptionFigColumn {
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
text-indent: 0.000000pt;
|
|
||||||
margin-top: 0.3em;
|
|
||||||
margin-bottom: 1.1em;
|
|
||||||
margin-right: 0.000000pt;
|
|
||||||
margin-left: 0.000000pt;
|
|
||||||
font-size: 90%;
|
|
||||||
font-weight: medium;
|
|
||||||
font-style: Italic;
|
|
||||||
color: #000000;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
font-family: "Arial";
|
|
||||||
}
|
|
||||||
P.Note {
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
text-indent: 0pt;
|
|
||||||
margin-top: 1.95em;
|
|
||||||
margin-bottom: 1.95em;
|
|
||||||
margin-right: 0.000000pt;
|
|
||||||
margin-left: 3.0em;
|
|
||||||
font-size: 110%;
|
|
||||||
font-weight: medium;
|
|
||||||
font-style: Italic;
|
|
||||||
color: #000000;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
font-family: "Arial";
|
|
||||||
}
|
|
||||||
EM.UILabel {
|
|
||||||
font-weight: Bold;
|
|
||||||
font-style: Regular;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
EM.CodeName {
|
|
||||||
font-weight: Bold;
|
|
||||||
font-style: Regular;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
font-family:"Courier New";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body, html { border: 0px }
|
|
||||||
|
|
||||||
/* following font face declarations need to be removed for DBCS */
|
|
||||||
|
|
||||||
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font: message-box; color: #000000}
|
|
||||||
pre { font-family: Courier, monospace}
|
|
||||||
|
|
||||||
/* end font face declarations */
|
|
||||||
|
|
||||||
/* following font size declarations should be OK for DBCS */
|
|
||||||
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font: message-box; }
|
|
||||||
pre { font-size: 100% }
|
|
||||||
code,samp { font-size: 100%; }
|
|
||||||
|
|
||||||
/* end font size declarations */
|
|
||||||
|
|
||||||
body { background: #FFFFFF}
|
|
||||||
h1 { font-size: 180%; font-weight: medium; margin-top: 0.28em; margin-bottom: 0.05em; color: Highlight }
|
|
||||||
h2 { font-size: 140%; font-weight: bold; margin-top: 0.22em; margin-bottom: 3; color: Highlight }
|
|
||||||
h3 { font-size: 110%; font-weight: bold; margin-top: 0.18em; margin-bottom: 3 }
|
|
||||||
h4 { font-size: 100%; font-weight: bold; margin-top: 0.2em; margin-bottom: 3; font-style: italic }
|
|
||||||
p { margin-top: 1.0em; margin-bottom: 1.0em }
|
|
||||||
pre { margin-left: 6; font-size: 90% }
|
|
||||||
a:link { color: #0000FF }
|
|
||||||
a:hover { color: #000080 }
|
|
||||||
a:visited { text-decoration: underline }
|
|
||||||
ul { margin-top: 0;
|
|
||||||
margin-bottom: 1.0em;
|
|
||||||
margin-left : 1.0em;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
li { margin-top: 0;
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
li p { margin-top: 0; margin-bottom: 0 }
|
|
||||||
ol { margin-top: 0;
|
|
||||||
margin-bottom: 10;
|
|
||||||
padding-left: 0;
|
|
||||||
margin-left: 1.4em }
|
|
||||||
dl { margin-top: 0; margin-bottom: 10 }
|
|
||||||
dt { margin-top: 0; margin-bottom: 0; font-weight: bold }
|
|
||||||
dd { margin-top: 0; margin-bottom: 0 }
|
|
||||||
strong { font-weight: bold}
|
|
||||||
em { font-style: italic}
|
|
||||||
var { font-style: italic}
|
|
||||||
div.revision { border-left-style: solid; border-left-width: thin;
|
|
||||||
border-left-color: #7B68EE; padding-left:5 }
|
|
||||||
th { font-weight: bold }
|
|
||||||
|
|
||||||
.figure-contents .mediaobject img {
|
|
||||||
width: 100%;
|
|
||||||
heigth: auto;
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
P.Code {
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
text-indent: 0.00pt;
|
|
||||||
margin-top: 0.000000pt;
|
|
||||||
margin-bottom: 0.000000pt;
|
|
||||||
margin-right: 0.000000pt;
|
|
||||||
margin-left: 15pt;
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
color: #4444CC;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
font-family: "Courier New", Courier, monospace;
|
|
||||||
}
|
|
||||||
H6.CaptionFigColumn {
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
text-indent: 0.000000pt;
|
|
||||||
margin-top: 3.000000pt;
|
|
||||||
margin-bottom: 11.000000pt;
|
|
||||||
margin-right: 0.000000pt;
|
|
||||||
margin-left: 0.000000pt;
|
|
||||||
font-size: 75%;
|
|
||||||
font-weight: bold;
|
|
||||||
font-style: Italic;
|
|
||||||
color: #000000;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
P.Note {
|
|
||||||
display: block;
|
|
||||||
text-align: left;
|
|
||||||
text-indent: 0pt;
|
|
||||||
margin-top: 19.500000pt;
|
|
||||||
margin-bottom: 19.500000pt;
|
|
||||||
margin-right: 0.000000pt;
|
|
||||||
margin-left: 30pt;
|
|
||||||
font-size: 110%;
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: Italic;
|
|
||||||
color: #000000;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
EM.UILabel {
|
|
||||||
font-weight: Bold;
|
|
||||||
font-style: normal;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
}
|
|
||||||
EM.CodeName {
|
|
||||||
font-weight: Bold;
|
|
||||||
font-style: normal;
|
|
||||||
text-decoration: none;
|
|
||||||
vertical-align: baseline;
|
|
||||||
text-transform: none;
|
|
||||||
font-family: "Courier New", Courier, monospace;
|
|
||||||
}
|
|
||||||
UL.NavList {
|
|
||||||
margin-left: 1.5em;
|
|
||||||
padding-left: 0px;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
body, html { border: 0px }
|
|
||||||
|
|
||||||
|
|
||||||
/* following font face declarations need to be removed for DBCS */
|
|
||||||
|
|
||||||
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font-family: Arial, Helvetica, sans-serif; color: #000000}
|
|
||||||
pre, code { font-family: "Courier New", Courier, monospace;}
|
|
||||||
|
|
||||||
/* end font face declarations */
|
|
||||||
|
|
||||||
@media print {
|
|
||||||
html { font-size: 12pt }
|
|
||||||
}
|
|
||||||
|
|
||||||
body { font-size: 83%; background: #FFFFFF; margin-bottom: 1em }
|
|
||||||
h1 { font-size: 180%; margin-top: 5px; margin-bottom: 1px }
|
|
||||||
h2 { font-size: 140%; margin-top: 25px; margin-bottom: 3px }
|
|
||||||
h3 { font-size: 110%; margin-top: 20px; margin-bottom: 3px }
|
|
||||||
h4 { font-size: 100%; margin-top: 20px; margin-bottom: 3px; font-style: italic }
|
|
||||||
p { margin-top: 10px; margin-bottom: 10px }
|
|
||||||
pre { font-size: 93%; margin-left: 6; color: #4444CC }
|
|
||||||
code { font-size: 93%; }
|
|
||||||
table { font-size: 100% } /* needed for quirks mode */
|
|
||||||
a:link { color: #0000FF }
|
|
||||||
a:hover { color: #000080 }
|
|
||||||
a:visited { text-decoration: underline }
|
|
||||||
ul { margin-top: 10px; margin-bottom: 10px; }
|
|
||||||
li { margin-top: 5px; margin-bottom: 5px; }
|
|
||||||
li p { margin-top: 5px; margin-bottom: 5px; }
|
|
||||||
ol { margin-top: 10px; margin-bottom: 10px; }
|
|
||||||
dl { margin-top: 10px; margin-bottom: 10px; }
|
|
||||||
dt { margin-top: 5px; margin-bottom: 5px; font-weight: bold; }
|
|
||||||
dd { margin-top: 5px; margin-bottom: 5px; }
|
|
||||||
strong { font-weight: bold}
|
|
||||||
em { font-style: italic}
|
|
||||||
var { font-style: italic}
|
|
||||||
div.revision { border-left-style: solid; border-left-width: thin;
|
|
||||||
border-left-color: #7B68EE; padding-left:5 }
|
|
||||||
th { font-weight: bold }
|
|
@ -1 +0,0 @@
|
|||||||
/*.png
|
|
@ -27,12 +27,12 @@ http://www.eclipse.org/legal/epl-v10.html
|
|||||||
</url>
|
</url>
|
||||||
|
|
||||||
<requires>
|
<requires>
|
||||||
|
<import plugin="org.codehaus.groovy" version="2.5.8" match="greaterOrEqual"/>
|
||||||
<import plugin="org.eclipse.osgi.services" version="3.4.0" match="greaterOrEqual"/>
|
<import plugin="org.eclipse.osgi.services" version="3.4.0" match="greaterOrEqual"/>
|
||||||
<import plugin="com.google.guava" version="15.0.0" match="greaterOrEqual"/>
|
<import plugin="com.google.guava" version="15.0.0" match="greaterOrEqual"/>
|
||||||
<import plugin="org.eclipse.osgi"/>
|
<import plugin="org.eclipse.osgi"/>
|
||||||
<import plugin="com.minres.scviewer.database" version="1.0.0" match="greaterOrEqual"/>
|
<import plugin="com.minres.scviewer.database" version="1.0.0" match="greaterOrEqual"/>
|
||||||
<import plugin="org.eclipse.core.runtime"/>
|
<import plugin="org.eclipse.core.runtime"/>
|
||||||
<import feature="org.eclipse.collections.feature" version="10.4.0.v20200820-2049"/>
|
|
||||||
</requires>
|
</requires>
|
||||||
|
|
||||||
<plugin
|
<plugin
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<version>3.0.0-SNAPSHOT</version>
|
<version>3.0.0-SNAPSHOT</version>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.0-SNAPSHOT</version>
|
||||||
|
@ -1 +0,0 @@
|
|||||||
/target/
|
|
@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<projectDescription>
|
|
||||||
<name>com.minres.scviewer.e4.help.feature</name>
|
|
||||||
<comment></comment>
|
|
||||||
<projects>
|
|
||||||
</projects>
|
|
||||||
<buildSpec>
|
|
||||||
<buildCommand>
|
|
||||||
<name>org.eclipse.pde.FeatureBuilder</name>
|
|
||||||
<arguments>
|
|
||||||
</arguments>
|
|
||||||
</buildCommand>
|
|
||||||
</buildSpec>
|
|
||||||
<natures>
|
|
||||||
<nature>org.eclipse.pde.FeatureNature</nature>
|
|
||||||
</natures>
|
|
||||||
</projectDescription>
|
|
@ -1 +0,0 @@
|
|||||||
bin.includes = feature.xml
|
|
@ -1,207 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<feature
|
|
||||||
id="com.minres.scviewer.e4.help.feature"
|
|
||||||
label="Feature"
|
|
||||||
version="1.0.0.qualifier"
|
|
||||||
provider-name="MINRES Technologies GmbH">
|
|
||||||
|
|
||||||
<description url="http://www.example.com/description">
|
|
||||||
[Enter Feature Description here.]
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<copyright url="http://www.example.com/copyright">
|
|
||||||
[Enter Copyright Description here.]
|
|
||||||
</copyright>
|
|
||||||
|
|
||||||
<license url="http://www.example.com/license">
|
|
||||||
[Enter License Description here.]
|
|
||||||
</license>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.help"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.help.webapp"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.help.base"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.apache.lucene.core"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.apache.lucene.analyzers-common"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.apache.lucene.analyzers-smartcn"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.core.net"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.security"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.security.linux.x86_64"
|
|
||||||
os="linux"
|
|
||||||
arch="x86_64"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
fragment="true"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="javax.el"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="javax.servlet"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="javax.servlet.jsp"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.http.jetty"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.http.registry"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.http.servlet"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.jsp.jasper"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.jsp.jasper.registry"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.apache.jasper.glassfish"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.jetty.http"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.jetty.io"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.jetty.security"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.jetty.server"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.jetty.servlet"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.jetty.util"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="com.minres.scviewer.e4.application.help"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
<plugin
|
|
||||||
id="org.eclipse.equinox.security.win32.x86_64"
|
|
||||||
os="win32"
|
|
||||||
arch="x86_64"
|
|
||||||
download-size="0"
|
|
||||||
install-size="0"
|
|
||||||
version="0.0.0"
|
|
||||||
fragment="true"
|
|
||||||
unpack="false"/>
|
|
||||||
|
|
||||||
</feature>
|
|
@ -1,12 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>com.minres.scviewer.e4.help.feature</artifactId>
|
|
||||||
<packaging>eclipse-feature</packaging>
|
|
||||||
<parent>
|
|
||||||
<groupId>com.minres.scviewer</groupId>
|
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
|
||||||
<version>2.16.1</version>
|
|
||||||
<relativePath>../..</relativePath>
|
|
||||||
</parent>
|
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
</project>
|
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.0-SNAPSHOT</version>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
<version>1.1.0-SNAPSHOT</version>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<packaging>eclipse-plugin</packaging>
|
<packaging>eclipse-plugin</packaging>
|
||||||
|
@ -78,24 +78,24 @@ public class SQLiteDbLoader implements IWaveformDbLoader {
|
|||||||
return streams;
|
return streams;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public boolean canLoad(File inputFile) {
|
public boolean canLoad(File inputFile) {
|
||||||
// if (!inputFile.isDirectory() && inputFile.exists()) {
|
if (!inputFile.isDirectory() && inputFile.exists()) {
|
||||||
// try(InputStream stream = new FileInputStream(inputFile)){
|
try(InputStream stream = new FileInputStream(inputFile)){
|
||||||
// byte[] buffer = new byte[x.length];
|
byte[] buffer = new byte[x.length];
|
||||||
// int readCnt = stream.read(buffer, 0, x.length);
|
int readCnt = stream.read(buffer, 0, x.length);
|
||||||
// if (readCnt == x.length) {
|
if (readCnt == x.length) {
|
||||||
// for (int i = 0; i < x.length; i++)
|
for (int i = 0; i < x.length; i++)
|
||||||
// if (buffer[i] != x[i])
|
if (buffer[i] != x[i])
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
// return true;
|
return true;
|
||||||
// } catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(IWaveformDb db, File file) throws InputFormatException {
|
public void load(IWaveformDb db, File file) throws InputFormatException {
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
<classpath>
|
<classpath>
|
||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="src" path="src/"/>
|
|
||||||
<classpathentry exported="true" kind="lib" path="lib/mapdb-3.0.7.jar" sourcepath="lib/mapdb-3.0.7-sources.jar">
|
<classpathentry exported="true" kind="lib" path="lib/mapdb-3.0.7.jar" sourcepath="lib/mapdb-3.0.7-sources.jar">
|
||||||
<attributes>
|
<attributes>
|
||||||
<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar!/"/>
|
<attribute name="javadoc_location" value="jar:platform:/resource/com.minres.scviewer.database.text/lib/mapdb-3.0.7-javadoc.jar!/"/>
|
||||||
</attributes>
|
</attributes>
|
||||||
</classpathentry>
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
<classpathentry exported="true" kind="lib" path="lib/kotlin-stdlib-1.2.42.jar"/>
|
<classpathentry exported="true" kind="lib" path="lib/kotlin-stdlib-1.2.42.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="lib/lz4-1.3.0.jar"/>
|
<classpathentry exported="true" kind="lib" path="lib/lz4-1.3.0.jar"/>
|
||||||
<classpathentry exported="true" kind="lib" path="lib/elsa-3.0.0-M5.jar"/>
|
<classpathentry exported="true" kind="lib" path="lib/elsa-3.0.0-M5.jar"/>
|
||||||
|
@ -2,15 +2,14 @@ Manifest-Version: 1.0
|
|||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: Textual transaction database
|
Bundle-Name: Textual transaction database
|
||||||
Bundle-SymbolicName: com.minres.scviewer.database.text
|
Bundle-SymbolicName: com.minres.scviewer.database.text
|
||||||
Bundle-Version: 4.0.1.qualifier
|
Bundle-Version: 4.0.0.qualifier
|
||||||
Bundle-Vendor: MINRES Technologies GmbH
|
Bundle-Vendor: MINRES Technologies GmbH
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
Bundle-RequiredExecutionEnvironment: JavaSE-11
|
||||||
Import-Package: org.osgi.framework;version="1.3.0"
|
Import-Package: org.osgi.framework;version="1.3.0"
|
||||||
Require-Bundle: com.minres.scviewer.database,
|
Require-Bundle: com.minres.scviewer.database,
|
||||||
org.eclipse.osgi.services;bundle-version="3.4.0",
|
org.eclipse.osgi.services;bundle-version="3.4.0",
|
||||||
com.google.guava;bundle-version="15.0.0",
|
com.google.guava;bundle-version="15.0.0",
|
||||||
org.eclipse.collections;bundle-version="10.4.0",
|
org.eclipse.collections;bundle-version="10.4.0"
|
||||||
org.apache.commons.compress;bundle-version="1.20.0"
|
|
||||||
Service-Component: OSGI-INF/component.xml
|
Service-Component: OSGI-INF/component.xml
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Automatic-Module-Name: com.minres.scviewer.database.text
|
Automatic-Module-Name: com.minres.scviewer.database.text
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoaderFactory">
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="TextDbLoader">
|
||||||
<implementation class="com.minres.scviewer.database.text.TextDbLoaderFactory"/>
|
<implementation class="com.minres.scviewer.database.text.TextDbLoader"/>
|
||||||
<service>
|
<service>
|
||||||
<provide interface="com.minres.scviewer.database.IWaveformDbLoaderFactory"/>
|
<provide interface="com.minres.scviewer.database.IWaveformDbLoader"/>
|
||||||
</service>
|
</service>
|
||||||
</scr:component>
|
</scr:component>
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>com.minres.scviewer.database.text</artifactId>
|
<artifactId>com.minres.scviewer.database.text</artifactId>
|
||||||
<version>4.0.1-SNAPSHOT</version>
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<packaging>eclipse-plugin</packaging>
|
<packaging>eclipse-plugin</packaging>
|
||||||
|
@ -13,7 +13,6 @@ package com.minres.scviewer.database.text;
|
|||||||
|
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -34,7 +33,6 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
|
|
||||||
import org.eclipse.collections.impl.map.mutable.UnifiedMap;
|
import org.eclipse.collections.impl.map.mutable.UnifiedMap;
|
||||||
import org.mapdb.DB;
|
import org.mapdb.DB;
|
||||||
import org.mapdb.DBMaker;
|
import org.mapdb.DBMaker;
|
||||||
@ -58,8 +56,6 @@ import com.minres.scviewer.database.tx.ITx;
|
|||||||
*/
|
*/
|
||||||
public class TextDbLoader implements IWaveformDbLoader {
|
public class TextDbLoader implements IWaveformDbLoader {
|
||||||
|
|
||||||
enum FileType { NONE, PLAIN, GZIP, LZ4};
|
|
||||||
|
|
||||||
/** the file size limit of a zipped txlog where the loader starts to use a file mapped database */
|
/** the file size limit of a zipped txlog where the loader starts to use a file mapped database */
|
||||||
private static final long MEMMAP_LIMIT=256l*1024l*1024l;
|
private static final long MEMMAP_LIMIT=256l*1024l*1024l;
|
||||||
|
|
||||||
@ -185,30 +181,45 @@ public class TextDbLoader implements IWaveformDbLoader {
|
|||||||
return relationTypes.values();
|
return relationTypes.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can load.
|
||||||
|
*
|
||||||
|
* @param inputFile the input file
|
||||||
|
* @return true, if successful
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean canLoad(File inputFile) {
|
||||||
|
if (!inputFile.isDirectory() && inputFile.exists()) {
|
||||||
|
boolean gzipped = isGzipped(inputFile);
|
||||||
|
try(InputStream stream = gzipped ? new GZIPInputStream(new FileInputStream(inputFile)) : new FileInputStream(inputFile)){
|
||||||
|
byte[] buffer = new byte[x.length];
|
||||||
|
int readCnt = stream.read(buffer, 0, x.length);
|
||||||
|
if (readCnt == x.length) {
|
||||||
|
for (int i = 0; i < x.length; i++)
|
||||||
|
if (buffer[i] != x[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if is gzipped.
|
* Checks if is gzipped.
|
||||||
*
|
*
|
||||||
* @param f the f
|
* @param f the f
|
||||||
* @return true, if is gzipped
|
* @return true, if is gzipped
|
||||||
*/
|
*/
|
||||||
static FileType getFileType(File f) {
|
private static boolean isGzipped(File f) {
|
||||||
try (InputStream is = new FileInputStream(f)) {
|
try (InputStream is = new FileInputStream(f)) {
|
||||||
byte[] signature = new byte[4];
|
byte[] signature = new byte[2];
|
||||||
int nread = is.read(signature); // read the gzip signature
|
int nread = is.read(signature); // read the gzip signature
|
||||||
if(nread >= 2 &&
|
return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b;
|
||||||
signature[0] == (byte) 0x1f &&
|
|
||||||
signature[1] == (byte) 0x8b)
|
|
||||||
return FileType.GZIP;
|
|
||||||
else if(nread>=4 &&
|
|
||||||
signature[0] == (byte) 0x04 &&
|
|
||||||
signature[1] == (byte) 0x22 &&
|
|
||||||
signature[2] == (byte) 0x4d &&
|
|
||||||
signature[3] == (byte) 0x18)
|
|
||||||
return FileType.LZ4;
|
|
||||||
else
|
|
||||||
return FileType.PLAIN;
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return FileType.NONE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,8 +235,8 @@ public class TextDbLoader implements IWaveformDbLoader {
|
|||||||
@Override
|
@Override
|
||||||
public void load(IWaveformDb db, File file) throws InputFormatException {
|
public void load(IWaveformDb db, File file) throws InputFormatException {
|
||||||
dispose();
|
dispose();
|
||||||
FileType fType = getFileType(file);
|
boolean gzipped = isGzipped(file);
|
||||||
if (file.length() < MEMMAP_LIMIT * (fType!=FileType.PLAIN ? 1 : 10)
|
if (file.length() < MEMMAP_LIMIT * (gzipped ? 1 : 10)
|
||||||
|| "memory".equals(System.getProperty("ScvBackingDB", "file")))
|
|| "memory".equals(System.getProperty("ScvBackingDB", "file")))
|
||||||
mapDb = DBMaker.memoryDirectDB().make();
|
mapDb = DBMaker.memoryDirectDB().make();
|
||||||
else {
|
else {
|
||||||
@ -245,13 +256,11 @@ public class TextDbLoader implements IWaveformDbLoader {
|
|||||||
try {
|
try {
|
||||||
|
|
||||||
parser.txSink = mapDb.hashMap("transactions", Serializer.LONG, Serializer.JAVA).create();
|
parser.txSink = mapDb.hashMap("transactions", Serializer.LONG, Serializer.JAVA).create();
|
||||||
InputStream is = new BufferedInputStream(new FileInputStream(file));
|
parser.parseInput(gzipped ? new GZIPInputStream(new FileInputStream(file)) : new FileInputStream(file));
|
||||||
parser.parseInput(fType==FileType.GZIP ? new GZIPInputStream(is) : fType==FileType.LZ4? new FramedLZ4CompressorInputStream(is) : is);
|
transactions = parser.txSink;
|
||||||
} catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
|
} catch (IllegalArgumentException | ArrayIndexOutOfBoundsException e) {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InputFormatException(e.toString());
|
throw new InputFormatException(e.toString());
|
||||||
} finally {
|
|
||||||
transactions = parser.txSink;
|
|
||||||
}
|
}
|
||||||
txStreams.values().parallelStream().forEach(TxStream::calculateConcurrency);
|
txStreams.values().parallelStream().forEach(TxStream::calculateConcurrency);
|
||||||
}
|
}
|
||||||
@ -331,22 +340,20 @@ public class TextDbLoader implements IWaveformDbLoader {
|
|||||||
* @throws IOException Signals that an I/O exception has occurred.
|
* @throws IOException Signals that an I/O exception has occurred.
|
||||||
* @throws InputFormatException Signals that the input format is wrong
|
* @throws InputFormatException Signals that the input format is wrong
|
||||||
*/
|
*/
|
||||||
void parseInput(InputStream inputStream) throws InputFormatException {
|
void parseInput(InputStream inputStream) throws IOException, InputFormatException {
|
||||||
try {
|
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||||
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
String curLine = reader.readLine();
|
||||||
String curLine = reader.readLine();
|
String nextLine = null;
|
||||||
String nextLine = null;
|
while ((nextLine = reader.readLine()) != null && curLine != null) {
|
||||||
while ((nextLine = reader.readLine()) != null && curLine != null) {
|
curLine = parseLine(curLine, nextLine);
|
||||||
curLine = parseLine(curLine, nextLine, false);
|
}
|
||||||
}
|
if (curLine != null)
|
||||||
if (curLine != null)
|
parseLine(curLine, nextLine);
|
||||||
parseLine(curLine, nextLine, true);
|
for(Entry<Long, ScvTx> e: transactionById.entrySet()) {
|
||||||
for(Entry<Long, ScvTx> e: transactionById.entrySet()) {
|
ScvTx scvTx = e.getValue();
|
||||||
ScvTx scvTx = e.getValue();
|
scvTx.endTime=loader.maxTime;
|
||||||
scvTx.endTime=loader.maxTime;
|
txSink.put(e.getKey(), scvTx);
|
||||||
txSink.put(e.getKey(), scvTx);
|
}
|
||||||
}
|
|
||||||
} catch(IOException e) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -378,87 +385,81 @@ public class TextDbLoader implements IWaveformDbLoader {
|
|||||||
* @throws IOException Signals that an I/O exception has occurred.
|
* @throws IOException Signals that an I/O exception has occurred.
|
||||||
* @throws InputFormatException Signals that the input format is wrong
|
* @throws InputFormatException Signals that the input format is wrong
|
||||||
*/
|
*/
|
||||||
private String parseLine(String curLine, String nextLine, boolean last) throws IOException, InputFormatException {
|
private String parseLine(String curLine, String nextLine) throws IOException, InputFormatException {
|
||||||
if(curLine.charAt(0)=='t') {
|
String[] tokens = curLine.split("\\s+");
|
||||||
String[] tokens = curLine.split(" ");
|
if ("tx_record_attribute".equals(tokens[0])) {
|
||||||
//if ("tx_record_attribute".equals(tokens[0]) && tokens.length>4) {
|
Long id = Long.parseLong(tokens[1]);
|
||||||
if (curLine.charAt(5)=='c' && tokens.length>4) {
|
String name = tokens[2].substring(1, tokens[2].length()-1);
|
||||||
Long id = Long.parseLong(tokens[1]);
|
DataType type = DataType.valueOf(tokens[3]);
|
||||||
String name = tokens[2].substring(1, tokens[2].length()-1);
|
String remaining = tokens.length > 5 ? String.join(" ", Arrays.copyOfRange(tokens, 5, tokens.length)) : "";
|
||||||
DataType type = DataType.valueOf(tokens[3]);
|
TxAttributeType attrType = getAttrType(name, type, AssociationType.RECORD);
|
||||||
String remaining = tokens.length > 5 ? String.join(" ", Arrays.copyOfRange(tokens, 5, tokens.length)) : "";
|
transactionById.get(id).attributes.add(new TxAttribute(attrType, getAttrString(attrType, remaining)));
|
||||||
TxAttributeType attrType = getAttrType(name, type, AssociationType.RECORD);
|
} else if ("tx_begin".equals(tokens[0])) {
|
||||||
transactionById.get(id).attributes.add(new TxAttribute(attrType, getAttrString(attrType, remaining)));
|
Long id = Long.parseLong(tokens[1]);
|
||||||
//} else if ("tx_begin".equals(tokens[0]) && tokens.length>4) {
|
Long genId = Long.parseLong(tokens[2]);
|
||||||
} else if (curLine.charAt(3)=='b' && tokens.length>4) {
|
TxGenerator gen = loader.txGenerators.get(genId);
|
||||||
Long id = Long.parseLong(tokens[1]);
|
ScvTx scvTx = new ScvTx(id, gen.stream.getId(), genId,
|
||||||
Long genId = Long.parseLong(tokens[2]);
|
Long.parseLong(tokens[3]) * stringToScale(tokens[4]));
|
||||||
TxGenerator gen = loader.txGenerators.get(genId);
|
loader.maxTime = loader.maxTime > scvTx.beginTime ? loader.maxTime : scvTx.beginTime;
|
||||||
ScvTx scvTx = new ScvTx(id, gen.stream.getId(), genId,
|
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||||
Long.parseLong(tokens[3]) * stringToScale(tokens[4]));
|
int idx = 0;
|
||||||
loader.maxTime = loader.maxTime > scvTx.beginTime ? loader.maxTime : scvTx.beginTime;
|
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||||
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
String[] attrTokens = nextLine.split("\\s+");
|
||||||
int idx = 0;
|
TxAttributeType attrType = gen.beginAttrs.get(idx);
|
||||||
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
||||||
String[] attrTokens = nextLine.split("\\s+");
|
scvTx.attributes.add(attr);
|
||||||
TxAttributeType attrType = gen.beginAttrs.get(idx);
|
idx++;
|
||||||
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
nextLine = reader.readLine();
|
||||||
scvTx.attributes.add(attr);
|
|
||||||
idx++;
|
|
||||||
nextLine = reader.readLine();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
transactionById.put(id, scvTx);
|
|
||||||
//} else if ("tx_end".equals(tokens[0]) && tokens.length>4) {
|
|
||||||
} else if (curLine.charAt(3)=='e' && tokens.length>4) {
|
|
||||||
Long id = Long.parseLong(tokens[1]);
|
|
||||||
ScvTx scvTx = transactionById.get(id);
|
|
||||||
assert Long.parseLong(tokens[2]) == scvTx.generatorId;
|
|
||||||
scvTx.endTime = Long.parseLong(tokens[3]) * stringToScale(tokens[4]);
|
|
||||||
loader.maxTime = loader.maxTime > scvTx.endTime ? loader.maxTime : scvTx.endTime;
|
|
||||||
TxGenerator gen = loader.txGenerators.get(scvTx.generatorId);
|
|
||||||
TxStream stream = loader.txStreams.get(gen.stream.getId());
|
|
||||||
if (scvTx.beginTime == scvTx.endTime) {
|
|
||||||
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
|
||||||
gen.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
|
||||||
} else {
|
|
||||||
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
|
||||||
gen.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
|
||||||
stream.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
|
||||||
gen.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
|
||||||
}
|
|
||||||
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
|
||||||
int idx = 0;
|
|
||||||
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
|
||||||
String[] attrTokens = nextLine.split("\\s+");
|
|
||||||
TxAttributeType attrType = gen.endAttrs.get(idx);
|
|
||||||
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
|
||||||
scvTx.attributes.add(attr);
|
|
||||||
idx++;
|
|
||||||
nextLine = reader.readLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
txSink.put(scvTx.getId(), scvTx);
|
|
||||||
transactionById.remove(id);
|
|
||||||
//} else if ("tx_relation".equals(tokens[0]) && tokens.length>3) {
|
|
||||||
} else if (curLine.charAt(5)=='l' && tokens.length>3) {
|
|
||||||
Long tr2 = Long.parseLong(tokens[2]);
|
|
||||||
Long tr1 = Long.parseLong(tokens[3]);
|
|
||||||
String relType = tokens[1].substring(1, tokens[1].length() - 1);
|
|
||||||
if (!loader.relationTypes.containsKey(relType))
|
|
||||||
loader.relationTypes.put(relType, RelationTypeFactory.create(relType));
|
|
||||||
ScvRelation rel = new ScvRelation(loader.relationTypes.get(relType), tr1, tr2);
|
|
||||||
loader.relationsOut.put(tr1, rel);
|
|
||||||
loader.relationsIn.put(tr2, rel);
|
|
||||||
}
|
}
|
||||||
} else if (curLine.length()>13 && "scv_tr_stream".equals(curLine.substring(0, 13))) {
|
transactionById.put(id, scvTx);
|
||||||
|
} else if ("tx_end".equals(tokens[0])) {
|
||||||
|
Long id = Long.parseLong(tokens[1]);
|
||||||
|
ScvTx scvTx = transactionById.get(id);
|
||||||
|
assert Long.parseLong(tokens[2]) == scvTx.generatorId;
|
||||||
|
scvTx.endTime = Long.parseLong(tokens[3]) * stringToScale(tokens[4]);
|
||||||
|
loader.maxTime = loader.maxTime > scvTx.endTime ? loader.maxTime : scvTx.endTime;
|
||||||
|
TxGenerator gen = loader.txGenerators.get(scvTx.generatorId);
|
||||||
|
TxStream stream = loader.txStreams.get(gen.stream.getId());
|
||||||
|
if (scvTx.beginTime == scvTx.endTime) {
|
||||||
|
stream.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
||||||
|
gen.addEvent(new TxEvent(loader, EventKind.SINGLE, id, scvTx.beginTime));
|
||||||
|
} else {
|
||||||
|
stream.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
||||||
|
gen.addEvent(new TxEvent(loader, EventKind.BEGIN, id, scvTx.beginTime));
|
||||||
|
stream.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
||||||
|
gen.addEvent(new TxEvent(loader, EventKind.END, id, scvTx.endTime));
|
||||||
|
}
|
||||||
|
if (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||||
|
int idx = 0;
|
||||||
|
while (nextLine != null && nextLine.charAt(0) == 'a') {
|
||||||
|
String[] attrTokens = nextLine.split("\\s+");
|
||||||
|
TxAttributeType attrType = gen.endAttrs.get(idx);
|
||||||
|
TxAttribute attr = new TxAttribute(attrType, getAttrString(attrType, attrTokens[1]));
|
||||||
|
scvTx.attributes.add(attr);
|
||||||
|
idx++;
|
||||||
|
nextLine = reader.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
txSink.put(scvTx.getId(), scvTx);
|
||||||
|
transactionById.remove(id);
|
||||||
|
} else if ("tx_relation".equals(tokens[0])) {
|
||||||
|
Long tr2 = Long.parseLong(tokens[2]);
|
||||||
|
Long tr1 = Long.parseLong(tokens[3]);
|
||||||
|
String relType = tokens[1].substring(1, tokens[1].length() - 1);
|
||||||
|
if (!loader.relationTypes.containsKey(relType))
|
||||||
|
loader.relationTypes.put(relType, RelationTypeFactory.create(relType));
|
||||||
|
ScvRelation rel = new ScvRelation(loader.relationTypes.get(relType), tr1, tr2);
|
||||||
|
loader.relationsOut.put(tr1, rel);
|
||||||
|
loader.relationsIn.put(tr2, rel);
|
||||||
|
} else if ("scv_tr_stream".equals(tokens[0])) {
|
||||||
Matcher matcher = scv_tr_stream.matcher(curLine);
|
Matcher matcher = scv_tr_stream.matcher(curLine);
|
||||||
if (matcher.matches()) {
|
if (matcher.matches()) {
|
||||||
Long id = Long.parseLong(matcher.group(1));
|
Long id = Long.parseLong(matcher.group(1));
|
||||||
TxStream stream = new TxStream(loader, id, matcher.group(2), matcher.group(3));
|
TxStream stream = new TxStream(loader, id, matcher.group(2), matcher.group(3));
|
||||||
add(id, stream);
|
add(id, stream);
|
||||||
}
|
}
|
||||||
} else if (curLine.length()>16 && "scv_tr_generator".equals(curLine.substring(0, 16))) {
|
} else if ("scv_tr_generator".equals(tokens[0])) {
|
||||||
Matcher matcher = scv_tr_generator.matcher(curLine);
|
Matcher matcher = scv_tr_generator.matcher(curLine);
|
||||||
if ((matcher.matches())) {
|
if ((matcher.matches())) {
|
||||||
Long id = Long.parseLong(matcher.group(1));
|
Long id = Long.parseLong(matcher.group(1));
|
||||||
@ -466,23 +467,23 @@ public class TextDbLoader implements IWaveformDbLoader {
|
|||||||
generator = new TxGenerator(loader, id, matcher.group(2), stream);
|
generator = new TxGenerator(loader, id, matcher.group(2), stream);
|
||||||
add(id, generator);
|
add(id, generator);
|
||||||
}
|
}
|
||||||
} else if (curLine.length()>15 && "begin_attribute".equals(curLine.substring(0, 15))) {
|
} else if ("begin_attribute".equals(tokens[0])) {
|
||||||
Matcher matcher = begin_attribute.matcher(curLine);
|
Matcher matcher = begin_attribute.matcher(curLine);
|
||||||
if ((matcher.matches())) {
|
if ((matcher.matches())) {
|
||||||
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)),
|
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)),
|
||||||
AssociationType.BEGIN);
|
AssociationType.BEGIN);
|
||||||
generator.beginAttrs.add(attrType);
|
generator.beginAttrs.add(attrType);
|
||||||
}
|
}
|
||||||
} else if (curLine.length()>13 && "end_attribute".equals(curLine.substring(0, 13))) {
|
} else if ("end_attribute".equals(tokens[0])) {
|
||||||
Matcher matcher = end_attribute.matcher(curLine);
|
Matcher matcher = end_attribute.matcher(curLine);
|
||||||
if ((matcher.matches())) {
|
if ((matcher.matches())) {
|
||||||
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)),
|
TxAttributeType attrType = getAttrType(matcher.group(2), DataType.valueOf(matcher.group(3)),
|
||||||
AssociationType.END);
|
AssociationType.END);
|
||||||
generator.endAttrs.add(attrType);
|
generator.endAttrs.add(attrType);
|
||||||
}
|
}
|
||||||
} else if (curLine.charAt(0) == ')') {
|
} else if (")".equals(tokens[0])) {
|
||||||
generator = null;
|
generator = null;
|
||||||
} else if(!last)
|
} else
|
||||||
throw new InputFormatException("Don't know what to do with: '" + curLine + "'");
|
throw new InputFormatException("Don't know what to do with: '" + curLine + "'");
|
||||||
return nextLine;
|
return nextLine;
|
||||||
}
|
}
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2012 IT Just working.
|
|
||||||
* Copyright (c) 2020 MINRES Technologies GmbH
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* IT Just working - initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package com.minres.scviewer.database.text;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
|
||||||
import org.apache.commons.compress.compressors.lz4.FramedLZ4CompressorInputStream;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.IWaveformDbLoader;
|
|
||||||
import com.minres.scviewer.database.IWaveformDbLoaderFactory;
|
|
||||||
import com.minres.scviewer.database.text.TextDbLoader.FileType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Class TextDbLoader.
|
|
||||||
*/
|
|
||||||
public class TextDbLoaderFactory implements IWaveformDbLoaderFactory {
|
|
||||||
|
|
||||||
/** The Constant x. */
|
|
||||||
static final byte[] x = "scv_tr_stream".getBytes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if f is gzipped.
|
|
||||||
*
|
|
||||||
* @param f the f
|
|
||||||
* @return true, if is gzipped
|
|
||||||
*/
|
|
||||||
private static boolean isGzipped(File f) {
|
|
||||||
try (InputStream is = new FileInputStream(f)) {
|
|
||||||
byte[] signature = new byte[2];
|
|
||||||
int nread = is.read(signature); // read the gzip signature
|
|
||||||
return nread == 2 && signature[0] == (byte) 0x1f && signature[1] == (byte) 0x8b;
|
|
||||||
} catch (IOException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can load.
|
|
||||||
*
|
|
||||||
* @param inputFile the input file
|
|
||||||
* @return true, if successful
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean canLoad(File inputFile) {
|
|
||||||
FileType fType = TextDbLoader.getFileType(inputFile);
|
|
||||||
try (InputStream is = new FileInputStream(inputFile)) {
|
|
||||||
InputStream plainIs = fType==FileType.GZIP ? new GZIPInputStream(is) : fType==FileType.LZ4? new FramedLZ4CompressorInputStream(is) : is;
|
|
||||||
byte[] buffer = new byte[x.length];
|
|
||||||
int readCnt = plainIs.read(buffer, 0, x.length);
|
|
||||||
if (readCnt == x.length) {
|
|
||||||
for (int i = 0; i < x.length; i++)
|
|
||||||
if (buffer[i] != x[i]) return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} catch (IOException e) {}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWaveformDbLoader getLoader() {
|
|
||||||
return new TextDbLoader();
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.minres.scviewer</groupId>
|
<groupId>com.minres.scviewer</groupId>
|
||||||
<artifactId>com.minres.scviewer.parent</artifactId>
|
<artifactId>com.minres.scviewer.parent</artifactId>
|
||||||
<version>2.16.1</version>
|
<version>2.13.0</version>
|
||||||
<relativePath>../..</relativePath>
|
<relativePath>../..</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<version>4.0.0-SNAPSHOT</version>
|
<version>4.0.0-SNAPSHOT</version>
|
||||||
|
@ -27,13 +27,9 @@ import com.minres.scviewer.database.tx.ITx;
|
|||||||
|
|
||||||
public interface IWaveformView extends PropertyChangeListener, ISelectionProvider{
|
public interface IWaveformView extends PropertyChangeListener, ISelectionProvider{
|
||||||
|
|
||||||
static final String CURSOR_PROPERTY = "cursor_time";
|
String CURSOR_PROPERTY = "cursor_time";
|
||||||
|
|
||||||
static final String MARKER_PROPERTY = "marker_time";
|
String MARKER_PROPERTY = "marker_time";
|
||||||
|
|
||||||
static final int CURSOR_POS = 0;
|
|
||||||
|
|
||||||
static final int MARKER_POS = 1;
|
|
||||||
|
|
||||||
public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
|
public static final RelationType NEXT_PREV_IN_STREAM = RelationTypeFactory.create("Prev/Next in stream");
|
||||||
|
|
||||||
@ -79,17 +75,23 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
|
|||||||
|
|
||||||
public void setHighliteRelation(RelationType relationType);
|
public void setHighliteRelation(RelationType relationType);
|
||||||
|
|
||||||
|
public long getMaxTime();
|
||||||
|
|
||||||
public void setMaxTime(long maxTime);
|
public void setMaxTime(long maxTime);
|
||||||
|
|
||||||
|
public void setZoomLevel(int scale);
|
||||||
|
|
||||||
|
public int getZoomLevel();
|
||||||
|
|
||||||
public void setCursorTime(long time);
|
public void setCursorTime(long time);
|
||||||
|
|
||||||
public void setMarkerTime(int marker, long time);
|
public void setMarkerTime(long time, int index);
|
||||||
|
|
||||||
public long getCursorTime();
|
public long getCursorTime();
|
||||||
|
|
||||||
public int getSelectedMarker();
|
public int getSelectedMarkerId();
|
||||||
|
|
||||||
public long getMarkerTime(int marker);
|
public long getMarkerTime(int index);
|
||||||
|
|
||||||
public void addPropertyChangeListener(PropertyChangeListener listener);
|
public void addPropertyChangeListener(PropertyChangeListener listener);
|
||||||
|
|
||||||
@ -99,18 +101,21 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide
|
|||||||
|
|
||||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
|
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener);
|
||||||
|
|
||||||
|
public String getScaledTime(long time);
|
||||||
|
|
||||||
|
public String[] getZoomLevels();
|
||||||
|
|
||||||
public List<ICursor> getCursorList();
|
public List<ICursor> getCursorList();
|
||||||
|
|
||||||
public void scrollHorizontal(int percent);
|
public long getBaselineTime();
|
||||||
|
|
||||||
public void scrollTo(int pos);
|
public void setBaselineTime(Long scale);
|
||||||
|
|
||||||
|
public void scrollHorizontal(int percent);
|
||||||
|
|
||||||
public void addDisposeListener( DisposeListener listener );
|
public void addDisposeListener( DisposeListener listener );
|
||||||
|
|
||||||
public void deleteSelectedTracks();
|
public void deleteSelectedTracks();
|
||||||
|
|
||||||
public TrackEntry addWaveform(IWaveform waveform, int pos);
|
public TrackEntry addWaveform(IWaveform waveform, int pos);
|
||||||
|
|
||||||
public IWaveformZoom getWaveformZoom();
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,24 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui;
|
|
||||||
|
|
||||||
public interface IWaveformZoom {
|
|
||||||
|
|
||||||
long getMaxVisibleTime();
|
|
||||||
|
|
||||||
long getMinVisibleTime();
|
|
||||||
|
|
||||||
void setMinVisibleTime(long scale);
|
|
||||||
|
|
||||||
long getMaxTime();
|
|
||||||
|
|
||||||
long getScale();
|
|
||||||
|
|
||||||
void setScale(long factor);
|
|
||||||
|
|
||||||
void setVisibleRange(long startTime, long endTime);
|
|
||||||
|
|
||||||
void centerAt(long time);
|
|
||||||
|
|
||||||
void zoom(ZoomKind kind);
|
|
||||||
|
|
||||||
String timeToString(long time);
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui;
|
|
||||||
|
|
||||||
public enum ZoomKind {IN, OUT, FIT, FULL}
|
|
@ -1,49 +1,14 @@
|
|||||||
package com.minres.scviewer.database.ui.swt;
|
package com.minres.scviewer.database.ui.swt;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
|
||||||
|
|
||||||
public class Constants {
|
public class Constants {
|
||||||
|
|
||||||
public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms", "s"};
|
public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms"};//, "s"};
|
||||||
public static final long[] UNIT_MULTIPLIER={1l, 1000l, 1000l*1000, 1000l*1000*1000, 1000l*1000*1000*1000, 1000l*1000*1000*1000*1000 };
|
|
||||||
|
|
||||||
//public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
|
public static final int[] UNIT_MULTIPLIER={1, 3, 10, 30, 100, 300};
|
||||||
public static final long[] SCALE_MULTIPLIER={1, 2, 5, 10, 20, 50, 100, 200, 500};
|
|
||||||
|
|
||||||
public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER";
|
public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_PROVIDER";
|
||||||
public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER";
|
public static final String HELP_PROVIDER_TAG = "TOOLTIP_HELP_PROVIDER";
|
||||||
|
|
||||||
public static final DecimalFormat TIME_FORMAT_FS = new DecimalFormat("#");
|
|
||||||
public static final DecimalFormat TIME_FORMAT_PS = new DecimalFormat("#");
|
|
||||||
public static final DecimalFormat TIME_FORMAT_NS = new DecimalFormat("#.0##");
|
|
||||||
public static final DecimalFormat TIME_FORMAT_UMS = new DecimalFormat("#.0#####");
|
|
||||||
public static final long[] POWERS_OF_TEN = {
|
|
||||||
1L,
|
|
||||||
10L,
|
|
||||||
100L,
|
|
||||||
1_000L,
|
|
||||||
10_000L,
|
|
||||||
100_000L,
|
|
||||||
1_000_000L,
|
|
||||||
10_000_000L,
|
|
||||||
100_000_000L,
|
|
||||||
1_000_000_000L,
|
|
||||||
10_000_000_000L,
|
|
||||||
100_000_000_000L,
|
|
||||||
1_000_000_000_000L,
|
|
||||||
10_000_000_000_000L,
|
|
||||||
100_000_000_000_000L,
|
|
||||||
1_000_000_000_000_000L};
|
|
||||||
|
|
||||||
public static DecimalFormat getTimeFormatForLevel(int idx) {
|
|
||||||
switch(idx) {
|
|
||||||
case 0: return TIME_FORMAT_FS;
|
|
||||||
case 1: return TIME_FORMAT_PS;
|
|
||||||
case 2: return TIME_FORMAT_NS;
|
|
||||||
default:
|
|
||||||
return TIME_FORMAT_UMS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private Constants() {}
|
private Constants() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ package com.minres.scviewer.database.ui.swt;
|
|||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Plugin;
|
import org.eclipse.core.runtime.Plugin;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.wb.swt.SWTResourceManager;
|
|
||||||
import org.osgi.framework.BundleContext;
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
public class DatabaseUiPlugin extends Plugin {
|
public class DatabaseUiPlugin extends Plugin {
|
||||||
@ -25,7 +24,6 @@ public class DatabaseUiPlugin extends Plugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop(BundleContext context) throws Exception {
|
public void stop(BundleContext context) throws Exception {
|
||||||
SWTResourceManager.dispose();
|
|
||||||
getLog().log(new Status(IStatus.OK, "org.eclipse.e4.core", "Stopping org.eclipse.e4.core bundle..."));
|
getLog().log(new Status(IStatus.OK, "org.eclipse.e4.core", "Stopping org.eclipse.e4.core bundle..."));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,6 +24,7 @@ import org.eclipse.swt.graphics.Rectangle;
|
|||||||
import org.eclipse.swt.widgets.Display;
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
|
||||||
import com.minres.scviewer.database.IEvent;
|
import com.minres.scviewer.database.IEvent;
|
||||||
|
import com.minres.scviewer.database.IHierNode;
|
||||||
import com.minres.scviewer.database.IWaveform;
|
import com.minres.scviewer.database.IWaveform;
|
||||||
import com.minres.scviewer.database.RelationType;
|
import com.minres.scviewer.database.RelationType;
|
||||||
import com.minres.scviewer.database.tx.ITx;
|
import com.minres.scviewer.database.tx.ITx;
|
||||||
@ -75,7 +76,7 @@ public class ArrowPainter implements IPainter {
|
|||||||
this.tx = newTx;
|
this.tx = newTx;
|
||||||
iRect = new LinkedList<>();
|
iRect = new LinkedList<>();
|
||||||
oRect = new LinkedList<>();
|
oRect = new LinkedList<>();
|
||||||
scaleFactor = waveCanvas.getScale();
|
scaleFactor = waveCanvas.getScaleFactor();
|
||||||
if (tx != null) {
|
if (tx != null) {
|
||||||
calculateGeometries();
|
calculateGeometries();
|
||||||
}
|
}
|
||||||
@ -109,23 +110,48 @@ public class ArrowPainter implements IPainter {
|
|||||||
protected void deriveGeom(Collection<ITxRelation> relations, List<LinkEntry> res, boolean useTarget) {
|
protected void deriveGeom(Collection<ITxRelation> relations, List<LinkEntry> res, boolean useTarget) {
|
||||||
for (ITxRelation iTxRelation : relations) {
|
for (ITxRelation iTxRelation : relations) {
|
||||||
ITx otherTx = useTarget ? iTxRelation.getTarget() : iTxRelation.getSource();
|
ITx otherTx = useTarget ? iTxRelation.getTarget() : iTxRelation.getSource();
|
||||||
for(IWaveform iWaveform: new IWaveform[]{otherTx.getStream(), otherTx.getGenerator()}) {
|
Rectangle bb = createLinkEntry(otherTx, otherTx.getStream());
|
||||||
if (waveCanvas.wave2painterMap.containsKey(iWaveform)) {
|
if(bb!=null){
|
||||||
IWaveformPainter painter = waveCanvas.wave2painterMap.get(iWaveform);
|
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
|
||||||
if(painter!=null) {
|
return;
|
||||||
int height = waveCanvas.styleProvider.getTrackHeight();
|
} else {
|
||||||
Rectangle bb = new Rectangle(
|
for(IHierNode gen:otherTx.getStream().getChildNodes()) {
|
||||||
(int) (otherTx.getBeginTime() / scaleFactor),
|
if(gen instanceof IWaveform) {
|
||||||
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx),
|
bb = createLinkEntry(otherTx, (IWaveform) gen);
|
||||||
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
|
if(bb!=null){
|
||||||
height);
|
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
|
||||||
res.add(new LinkEntry(bb, iTxRelation.getRelationType()));
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Rectangle createLinkEntry(ITx otherTx, IWaveform iWaveform) {
|
||||||
|
if (waveCanvas.wave2painterMap.containsKey(iWaveform)) {
|
||||||
|
IWaveformPainter painter = waveCanvas.wave2painterMap.get(otherTx.getStream());
|
||||||
|
if(painter==null) {
|
||||||
|
for(IHierNode gen:otherTx.getStream().getChildNodes()) {
|
||||||
|
if(gen instanceof IWaveform) {
|
||||||
|
painter = waveCanvas.wave2painterMap.get(gen);
|
||||||
|
if(painter!=null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(painter!=null) {
|
||||||
|
int height = waveCanvas.styleProvider.getTrackHeight();
|
||||||
|
return new Rectangle(
|
||||||
|
(int) (otherTx.getBeginTime() / scaleFactor),
|
||||||
|
waveCanvas.rulerHeight + painter.getVerticalOffset() + height * getConcurrencyIndex(otherTx),
|
||||||
|
(int) ((otherTx.getEndTime() - otherTx.getBeginTime()) / scaleFactor),
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintArea(Projection proj, Rectangle clientRect) {
|
public void paintArea(Projection proj, Rectangle clientRect) {
|
||||||
yCtrlOffset = waveCanvas.styleProvider.getTrackHeight()/2;
|
yCtrlOffset = waveCanvas.styleProvider.getTrackHeight()/2;
|
||||||
@ -133,7 +159,7 @@ public class ArrowPainter implements IPainter {
|
|||||||
Color highliteColor = waveCanvas.styleProvider.getColor(WaveformColors.REL_ARROW_HIGHLITE);
|
Color highliteColor = waveCanvas.styleProvider.getColor(WaveformColors.REL_ARROW_HIGHLITE);
|
||||||
|
|
||||||
if(tx==null) return;
|
if(tx==null) return;
|
||||||
scaleFactor = waveCanvas.getScale();
|
scaleFactor = waveCanvas.getScaleFactor();
|
||||||
if(calculateGeometries())
|
if(calculateGeometries())
|
||||||
return;
|
return;
|
||||||
int correctionValue = (int)(selectionOffset);
|
int correctionValue = (int)(selectionOffset);
|
||||||
|
@ -65,7 +65,7 @@ public class CursorPainter implements IPainter, ICursor {
|
|||||||
Rectangle area = proj.unProject(clientRect);
|
Rectangle area = proj.unProject(clientRect);
|
||||||
if(!waveCanvas.painterList.isEmpty()){
|
if(!waveCanvas.painterList.isEmpty()){
|
||||||
|
|
||||||
long scaleFactor=waveCanvas.getScale();
|
long scaleFactor=waveCanvas.getScaleFactor();
|
||||||
long beginPos = area.x;
|
long beginPos = area.x;
|
||||||
|
|
||||||
maxPosX = area.x + area.width;
|
maxPosX = area.x + area.width;
|
||||||
@ -83,7 +83,8 @@ public class CursorPainter implements IPainter, ICursor {
|
|||||||
proj.drawLine(x, top, x, area.y+area.height);
|
proj.drawLine(x, top, x, area.y+area.height);
|
||||||
proj.setBackground(drawColor);
|
proj.setBackground(drawColor);
|
||||||
proj.setForeground(textColor);
|
proj.setForeground(textColor);
|
||||||
proj.drawText(waveCanvas.timeToString(time), x+1, top);
|
double dTime=time;
|
||||||
|
proj.drawText((dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,21 +10,22 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.minres.scviewer.database.ui.swt.internal;
|
package com.minres.scviewer.database.ui.swt.internal;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.graphics.Color;
|
import org.eclipse.swt.graphics.Color;
|
||||||
import org.eclipse.swt.graphics.GC;
|
import org.eclipse.swt.graphics.GC;
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
import org.eclipse.wb.swt.SWTResourceManager;
|
import org.eclipse.wb.swt.SWTResourceManager;
|
||||||
|
|
||||||
import com.minres.scviewer.database.ui.swt.Constants;
|
|
||||||
|
|
||||||
public class RulerPainter implements IPainter {
|
public class RulerPainter implements IPainter {
|
||||||
protected final WaveformCanvas waveCanvas;
|
protected final WaveformCanvas waveCanvas;
|
||||||
|
|
||||||
static final int RULER_TICK_MINOR = 10;
|
static final int RULER_TICK_MINOR = 10;
|
||||||
static final int RULER_TICK_MAJOR = 100;
|
static final int RULER_TICK_MAJOR = 100;
|
||||||
|
|
||||||
|
static final DecimalFormat df = new DecimalFormat("#.00####");
|
||||||
|
|
||||||
public RulerPainter(WaveformCanvas waveCanvas) {
|
public RulerPainter(WaveformCanvas waveCanvas) {
|
||||||
this.waveCanvas=waveCanvas;
|
this.waveCanvas=waveCanvas;
|
||||||
}
|
}
|
||||||
@ -38,26 +39,26 @@ public class RulerPainter implements IPainter {
|
|||||||
Color headerBgColor = waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
|
Color headerBgColor = waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
|
||||||
if(headerBgColor.isDisposed())
|
if(headerBgColor.isDisposed())
|
||||||
headerBgColor=SWTResourceManager.getColor(255,255,255);
|
headerBgColor=SWTResourceManager.getColor(255,255,255);
|
||||||
|
String unit=waveCanvas.getUnitStr();
|
||||||
|
int unitMultiplier=waveCanvas.getUnitMultiplier();
|
||||||
|
long scaleFactor=waveCanvas.getScaleFactor();
|
||||||
|
|
||||||
long scaleFactor=waveCanvas.getScale();
|
long startPos=area.x*scaleFactor;
|
||||||
long startTime=waveCanvas.getMinVisibleTime();
|
long startVal=startPos - proj.getTranslation().x*scaleFactor;
|
||||||
long endTime=waveCanvas.getMaxVisibleTime();
|
long endPos=startPos+area.width*scaleFactor;
|
||||||
|
|
||||||
|
long rulerTickMinor = RULER_TICK_MINOR*scaleFactor;
|
||||||
|
long rulerTickMajor = RULER_TICK_MAJOR*scaleFactor;
|
||||||
|
|
||||||
long multiplier = Constants.POWERS_OF_TEN[waveCanvas.getScaleMagnitude()];
|
|
||||||
long rulerTickMinor = RULER_TICK_MINOR*multiplier;
|
|
||||||
long rulerTickMajor = RULER_TICK_MAJOR*multiplier;
|
|
||||||
if((endTime-startTime)/rulerTickMinor>area.width/5) {
|
|
||||||
rulerTickMinor*=10;
|
|
||||||
rulerTickMajor*=10;
|
|
||||||
}
|
|
||||||
int minorTickY = waveCanvas.rulerHeight-5;
|
int minorTickY = waveCanvas.rulerHeight-5;
|
||||||
int majorTickY = waveCanvas.rulerHeight-15;
|
int majorTickY = waveCanvas.rulerHeight-15;
|
||||||
int textY=waveCanvas.rulerHeight-30;
|
int textY=waveCanvas.rulerHeight-20;
|
||||||
int baselineY=waveCanvas.rulerHeight - 1;
|
int baselineY=waveCanvas.rulerHeight - 1;
|
||||||
int bottom=waveCanvas.rulerHeight - 2;
|
int bottom=waveCanvas.rulerHeight - 2;
|
||||||
|
|
||||||
long startTickTime = startTime+rulerTickMinor-(startTime % rulerTickMinor);
|
long modulo = startVal % rulerTickMinor;
|
||||||
long majorTickDist = rulerTickMajor/scaleFactor;
|
long startMinorIncrPos = startPos+rulerTickMinor-modulo;
|
||||||
|
long startMinorIncrVal = startVal+rulerTickMinor-modulo;
|
||||||
|
|
||||||
gc.setBackground(waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
|
gc.setBackground(waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
|
||||||
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, waveCanvas.rulerHeight));
|
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, waveCanvas.rulerHeight));
|
||||||
@ -65,22 +66,13 @@ public class RulerPainter implements IPainter {
|
|||||||
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, baselineY));
|
gc.fillRectangle(new Rectangle(area.x, area.y, area.width, baselineY));
|
||||||
gc.setForeground(headerFgColor);
|
gc.setForeground(headerFgColor);
|
||||||
gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom);
|
gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom);
|
||||||
int maxTextLength=0;
|
|
||||||
for (long tickTime = startTickTime; tickTime < endTime; tickTime+= rulerTickMinor) {
|
for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) {
|
||||||
if ((tickTime % rulerTickMajor) == 0) {
|
int x0Pos = (int) (pos/scaleFactor);
|
||||||
Point textSize = gc.textExtent(waveCanvas.timeToString(tickTime));
|
long x0Val = tick/scaleFactor;
|
||||||
maxTextLength=textSize.x>maxTextLength?textSize.x:maxTextLength;
|
if ((tick % rulerTickMajor) == 0) {
|
||||||
}
|
gc.drawText(df.format(x0Val*unitMultiplier)+unit, x0Pos, area.y+textY);
|
||||||
}
|
|
||||||
boolean drawEvery = majorTickDist>maxTextLength;
|
|
||||||
boolean drawText=true;
|
|
||||||
for (long tickTime = startTickTime; tickTime < endTime; tickTime+= rulerTickMinor) {
|
|
||||||
int x0Pos = (int) (tickTime/scaleFactor) + proj.getTranslation().x;
|
|
||||||
if ((tickTime % rulerTickMajor) == 0) {
|
|
||||||
if(drawEvery || drawText)
|
|
||||||
gc.drawText(waveCanvas.timeToString(tickTime), x0Pos, area.y+textY);
|
|
||||||
gc.drawLine(x0Pos, area.y+majorTickY, x0Pos,area.y+ bottom);
|
gc.drawLine(x0Pos, area.y+majorTickY, x0Pos,area.y+ bottom);
|
||||||
drawText=!drawText;
|
|
||||||
} else {
|
} else {
|
||||||
gc.drawLine(x0Pos, area.y+minorTickY, x0Pos, area.y+bottom);
|
gc.drawLine(x0Pos, area.y+minorTickY, x0Pos, area.y+bottom);
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ public class SignalPainter extends TrackPainter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getXPosEnd(long time) {
|
private int getXPosEnd(long time) {
|
||||||
long ltmp = time / this.waveCanvas.getScale();
|
long ltmp = time / this.waveCanvas.getScaleFactor();
|
||||||
return ltmp > maxPosX ? maxPosX : (int) ltmp;
|
return ltmp > maxPosX ? maxPosX : (int) ltmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ public class SignalPainter extends TrackPainter {
|
|||||||
proj.setFillRule(SWT.FILL_EVEN_ODD);
|
proj.setFillRule(SWT.FILL_EVEN_ODD);
|
||||||
proj.fillRectangle(area);
|
proj.fillRectangle(area);
|
||||||
|
|
||||||
long scaleFactor = this.waveCanvas.getScale();
|
long scaleFactor = this.waveCanvas.getScaleFactor();
|
||||||
long beginPos = area.x;
|
long beginPos = area.x;
|
||||||
long beginTime = beginPos*scaleFactor;
|
long beginTime = beginPos*scaleFactor;
|
||||||
long endTime = beginTime + area.width*scaleFactor;
|
long endTime = beginTime + area.width*scaleFactor;
|
||||||
@ -114,7 +114,7 @@ public class SignalPainter extends TrackPainter {
|
|||||||
yOffsetT = this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y;
|
yOffsetT = this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y;
|
||||||
yOffsetM = this.waveCanvas.styleProvider.getTrackHeight() / 2 + area.y;
|
yOffsetM = this.waveCanvas.styleProvider.getTrackHeight() / 2 + area.y;
|
||||||
yOffsetB = 4 * this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y;
|
yOffsetB = 4 * this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y;
|
||||||
int xSigChangeBeginVal = Math.max(area.x, (int) (left.time / this.waveCanvas.getScale()));
|
int xSigChangeBeginVal = Math.max(area.x, (int) (left.time / this.waveCanvas.getScaleFactor()));
|
||||||
int xSigChangeBeginPos = area.x;
|
int xSigChangeBeginPos = area.x;
|
||||||
int xSigChangeEndPos = Math.max(area.x, getXPosEnd(right.time));
|
int xSigChangeEndPos = Math.max(area.x, getXPosEnd(right.time));
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ public class SignalPainter extends TrackPainter {
|
|||||||
right.time = endTime;
|
right.time = endTime;
|
||||||
} else {
|
} else {
|
||||||
multiple = true;
|
multiple = true;
|
||||||
long eTime = (xSigChangeBeginVal + 1) * this.waveCanvas.getScale();
|
long eTime = (xSigChangeBeginVal + 1) * this.waveCanvas.getScaleFactor();
|
||||||
right.set(entries.floorEntry(eTime), endTime);
|
right.set(entries.floorEntry(eTime), endTime);
|
||||||
right.time = eTime;
|
right.time = eTime;
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ public class SignalPainter extends TrackPainter {
|
|||||||
multiple = false;
|
multiple = false;
|
||||||
if (xSigChangeEndPos == xSigChangeBeginPos) {
|
if (xSigChangeEndPos == xSigChangeBeginPos) {
|
||||||
multiple = true;
|
multiple = true;
|
||||||
long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScale();
|
long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor();
|
||||||
EventEntry entry = entries.floorEntry(eTime);
|
EventEntry entry = entries.floorEntry(eTime);
|
||||||
if(entry!=null && entry.timestamp> right.time)
|
if(entry!=null && entry.timestamp> right.time)
|
||||||
right.set(entry, endTime);
|
right.set(entry, endTime);
|
||||||
@ -356,7 +356,7 @@ public class SignalPainter extends TrackPainter {
|
|||||||
public RealStencil(IEventList entries, Object left, boolean continous) {
|
public RealStencil(IEventList entries, Object left, boolean continous) {
|
||||||
this.continous=continous;
|
this.continous=continous;
|
||||||
Collection<EventEntry> values = entries.entrySet();
|
Collection<EventEntry> values = entries.entrySet();
|
||||||
minVal=((DoubleVal) left).value;
|
minVal=(Double) left;
|
||||||
range=2.0;
|
range=2.0;
|
||||||
if(!values.isEmpty()) {
|
if(!values.isEmpty()) {
|
||||||
double maxVal=minVal;
|
double maxVal=minVal;
|
||||||
|
@ -67,7 +67,7 @@ public class StreamPainter extends TrackPainter{
|
|||||||
proj.setFillRule(SWT.FILL_EVEN_ODD);
|
proj.setFillRule(SWT.FILL_EVEN_ODD);
|
||||||
proj.fillRectangle(area);
|
proj.fillRectangle(area);
|
||||||
|
|
||||||
long scaleFactor = this.waveCanvas.getScale();
|
long scaleFactor = this.waveCanvas.getScaleFactor();
|
||||||
long beginPos = area.x;
|
long beginPos = area.x;
|
||||||
long beginTime = beginPos*scaleFactor;
|
long beginTime = beginPos*scaleFactor;
|
||||||
long endTime = beginTime + area.width*scaleFactor;
|
long endTime = beginTime + area.width*scaleFactor;
|
||||||
@ -130,8 +130,8 @@ public class StreamPainter extends TrackPainter{
|
|||||||
|
|
||||||
int offset = concurrencyIndex*this.waveCanvas.styleProvider.getTrackHeight();
|
int offset = concurrencyIndex*this.waveCanvas.styleProvider.getTrackHeight();
|
||||||
Rectangle bb = new Rectangle(
|
Rectangle bb = new Rectangle(
|
||||||
(int)(tx.getBeginTime()/this.waveCanvas.getScale()), area.y+offset+txBase,
|
(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()), area.y+offset+txBase,
|
||||||
(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScale()), txHeight);
|
(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScaleFactor()), txHeight);
|
||||||
|
|
||||||
if(bb.x+bb.width<area.x || bb.x>area.x+area.width) return;
|
if(bb.x+bb.width<area.x || bb.x>area.x+area.width) return;
|
||||||
if(bb.width==0){
|
if(bb.width==0){
|
||||||
@ -155,7 +155,7 @@ public class StreamPainter extends TrackPainter{
|
|||||||
|
|
||||||
public ITx getClicked(Point point) {
|
public ITx getClicked(Point point) {
|
||||||
int lane=point.y/waveCanvas.styleProvider.getTrackHeight();
|
int lane=point.y/waveCanvas.styleProvider.getTrackHeight();
|
||||||
EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScale());
|
EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor());
|
||||||
if(firstTx!=null){
|
if(firstTx!=null){
|
||||||
do {
|
do {
|
||||||
ITx tx = getTxFromEntry(lane, point.x, firstTx.events);
|
ITx tx = getTxFromEntry(lane, point.x, firstTx.events);
|
||||||
@ -175,9 +175,9 @@ public class StreamPainter extends TrackPainter{
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected ITx getTxFromEntry(int lane, int offset, IEvent[] firstTx) {
|
protected ITx getTxFromEntry(int lane, int offset, IEvent[] firstTx) {
|
||||||
long timePoint=offset*waveCanvas.getScale();
|
long timePoint=offset*waveCanvas.getScaleFactor();
|
||||||
long timePointLow=(offset-5)*waveCanvas.getScale();
|
long timePointLow=(offset-5)*waveCanvas.getScaleFactor();
|
||||||
long timePointHigh=(offset+5)*waveCanvas.getScale();
|
long timePointHigh=(offset+5)*waveCanvas.getScaleFactor();
|
||||||
for(IEvent e:firstTx){
|
for(IEvent e:firstTx){
|
||||||
if(e instanceof ITxEvent) {
|
if(e instanceof ITxEvent) {
|
||||||
ITxEvent evt = (ITxEvent) e;
|
ITxEvent evt = (ITxEvent) e;
|
||||||
|
@ -35,15 +35,14 @@ public class TrackAreaPainter implements IPainter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void paintArea(Projection proj, Rectangle a) {
|
public void paintArea(Projection proj, Rectangle a) {
|
||||||
Rectangle area = proj.unProject(new Rectangle(a.x, a.y+waveCanvas.rulerHeight, a.width, a.height-waveCanvas.rulerHeight));
|
Rectangle area = proj.unProject(new Rectangle(a.x, a.y+waveCanvas.rulerHeight, a.width, a.height-waveCanvas.rulerHeight));
|
||||||
proj.setBackground(this.waveCanvas.styleProvider.getColor(WaveformColors.TRACK_BG_EVEN));
|
proj.setBackground(this.waveCanvas.styleProvider.getColor(WaveformColors.TRACK_BG_EVEN));
|
||||||
proj.setFillRule(SWT.FILL_EVEN_ODD);
|
proj.setFillRule(SWT.FILL_EVEN_ODD);
|
||||||
proj.fillRectangle(area);
|
proj.fillRectangle(area);
|
||||||
if(trackVerticalOffset.size()>0){
|
if(trackVerticalOffset.size()>0){
|
||||||
Integer firstKey=trackVerticalOffset.floorKey(area.y);
|
Integer firstKey=trackVerticalOffset.floorKey(area.y);
|
||||||
if(firstKey==null) firstKey=trackVerticalOffset.firstKey();
|
if(firstKey==null) firstKey=trackVerticalOffset.firstKey();
|
||||||
Integer lastKey = trackVerticalOffset.floorKey(area.y+area.height);
|
Integer lastKey = trackVerticalOffset.floorKey(area.y+area.height);
|
||||||
//if(lastKey==null) lastKey= trackVerticalOffset.lastKey();
|
|
||||||
Rectangle subArea = new Rectangle(area.x, 0, area.width, 0);
|
Rectangle subArea = new Rectangle(area.x, 0, area.width, 0);
|
||||||
if(lastKey.equals(firstKey)){
|
if(lastKey.equals(firstKey)){
|
||||||
subArea.y=firstKey;
|
subArea.y=firstKey;
|
||||||
|
@ -42,39 +42,32 @@ import com.minres.scviewer.database.tx.ITx;
|
|||||||
import com.minres.scviewer.database.tx.ITxEvent;
|
import com.minres.scviewer.database.tx.ITxEvent;
|
||||||
import com.minres.scviewer.database.ui.IWaveformStyleProvider;
|
import com.minres.scviewer.database.ui.IWaveformStyleProvider;
|
||||||
import com.minres.scviewer.database.ui.IWaveformView;
|
import com.minres.scviewer.database.ui.IWaveformView;
|
||||||
import com.minres.scviewer.database.ui.IWaveformZoom;
|
|
||||||
import com.minres.scviewer.database.ui.TrackEntry;
|
import com.minres.scviewer.database.ui.TrackEntry;
|
||||||
import com.minres.scviewer.database.ui.ZoomKind;
|
|
||||||
import com.minres.scviewer.database.ui.swt.Constants;
|
import com.minres.scviewer.database.ui.swt.Constants;
|
||||||
import com.minres.scviewer.database.ui.swt.internal.slider.ZoomBar;
|
|
||||||
|
|
||||||
public class WaveformCanvas extends Canvas implements IWaveformZoom{
|
public class WaveformCanvas extends Canvas {
|
||||||
|
|
||||||
public static final long ZOOM_FIT = -2;
|
private boolean doubleBuffering = true;
|
||||||
|
|
||||||
public static final long ZOOM_FULL = -1;
|
IWaveformStyleProvider styleProvider;
|
||||||
|
|
||||||
private static final int INITIAL_ZOOM_BAR_MAX = 1000;
|
private long scaleFactor = 1000000L; // 1ns
|
||||||
|
|
||||||
private boolean doubleBuffering = true;
|
String unit="ns";
|
||||||
|
|
||||||
IWaveformStyleProvider styleProvider;
|
private int level = 12;
|
||||||
|
|
||||||
private int scaleMagnitude = 6;
|
private long maxTime;
|
||||||
|
|
||||||
private long scaleFactor = Constants.POWERS_OF_TEN[scaleMagnitude];
|
protected Point origin; /* original size */
|
||||||
|
|
||||||
private long maxTime;
|
protected int rulerHeight=40;
|
||||||
|
|
||||||
protected Point origin; /* original size */
|
protected List<IPainter> painterList;
|
||||||
|
|
||||||
protected int rulerHeight=40;
|
ITx currentSelection;
|
||||||
|
|
||||||
protected List<IPainter> painterList;
|
private List<SelectionAdapter> selectionListeners;
|
||||||
|
|
||||||
ITx currentSelection;
|
|
||||||
|
|
||||||
private List<SelectionAdapter> selectionListeners;
|
|
||||||
|
|
||||||
private RulerPainter rulerPainter;
|
private RulerPainter rulerPainter;
|
||||||
|
|
||||||
@ -84,525 +77,446 @@ public class WaveformCanvas extends Canvas implements IWaveformZoom{
|
|||||||
|
|
||||||
private List<CursorPainter> cursorPainters;
|
private List<CursorPainter> cursorPainters;
|
||||||
|
|
||||||
private ZoomBar horizontal;
|
|
||||||
|
|
||||||
private int[] lastHorSelection;
|
|
||||||
|
|
||||||
private long sliderScaleFactor = 1;
|
|
||||||
|
|
||||||
private ScrollBar vertical;
|
|
||||||
|
|
||||||
HashMap<IWaveform, IWaveformPainter> wave2painterMap;
|
HashMap<IWaveform, IWaveformPainter> wave2painterMap;
|
||||||
|
/**
|
||||||
public WaveformCanvas(final Composite parent, int style, IWaveformStyleProvider styleProvider, ZoomBar.IProvider scrollbarProvider) {
|
* Constructor for ScrollableCanvas.
|
||||||
super(parent, (style & ~SWT.H_SCROLL) | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.V_SCROLL );
|
*
|
||||||
this.styleProvider=styleProvider;
|
* @param parent
|
||||||
addControlListener(new ControlAdapter() { /* resize listener. */
|
* the parent of this control.super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.V_SCROLL | SWT.H_SCROLL);
|
||||||
|
* @param style
|
||||||
|
* the style of this control.
|
||||||
|
*/
|
||||||
|
public WaveformCanvas(final Composite parent, int style, IWaveformStyleProvider styleProvider) {
|
||||||
|
super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL);
|
||||||
|
this.styleProvider=styleProvider;
|
||||||
|
addControlListener(new ControlAdapter() { /* resize listener. */
|
||||||
@Override
|
@Override
|
||||||
public void controlResized(ControlEvent event) {
|
public void controlResized(ControlEvent event) {
|
||||||
syncSb();
|
syncScrollBars();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addPaintListener((final PaintEvent event) -> paint(event.gc));
|
addPaintListener((final PaintEvent event) -> paint(event.gc));
|
||||||
painterList = new LinkedList<>();
|
painterList = new LinkedList<>();
|
||||||
origin = new Point(0, 0);
|
origin = new Point(0, 0);
|
||||||
selectionListeners = new LinkedList<>();
|
selectionListeners = new LinkedList<>();
|
||||||
cursorPainters= new ArrayList<>();
|
cursorPainters= new ArrayList<>();
|
||||||
wave2painterMap=new HashMap<>();
|
wave2painterMap=new HashMap<>();
|
||||||
|
|
||||||
horizontal = scrollbarProvider.getScrollBar();
|
initScrollBars();
|
||||||
vertical = getVerticalBar();
|
|
||||||
initScrollBars();
|
|
||||||
// order is important: it is bottom to top
|
// order is important: it is bottom to top
|
||||||
trackAreaPainter=new TrackAreaPainter(this);
|
trackAreaPainter=new TrackAreaPainter(this);
|
||||||
painterList.add(trackAreaPainter);
|
painterList.add(trackAreaPainter);
|
||||||
arrowPainter=new ArrowPainter(this, IWaveformView.NEXT_PREV_IN_STREAM);
|
arrowPainter=new ArrowPainter(this, IWaveformView.NEXT_PREV_IN_STREAM);
|
||||||
painterList.add(arrowPainter);
|
painterList.add(arrowPainter);
|
||||||
rulerPainter=new RulerPainter(this);
|
rulerPainter=new RulerPainter(this);
|
||||||
painterList.add(rulerPainter);
|
painterList.add(rulerPainter);
|
||||||
CursorPainter cp = new CursorPainter(this, getScale() * 10, cursorPainters.size()-1);
|
CursorPainter cp = new CursorPainter(this, scaleFactor * 10, cursorPainters.size()-1);
|
||||||
painterList.add(cp);
|
painterList.add(cp);
|
||||||
cursorPainters.add(cp);
|
cursorPainters.add(cp);
|
||||||
CursorPainter marker = new CursorPainter(this, getScale() * 100, cursorPainters.size()-1);
|
CursorPainter marker = new CursorPainter(this, scaleFactor * 100, cursorPainters.size()-1);
|
||||||
painterList.add(marker);
|
painterList.add(marker);
|
||||||
cursorPainters.add(marker);
|
cursorPainters.add(marker);
|
||||||
wave2painterMap=new HashMap<>();
|
wave2painterMap=new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCursoPainter(CursorPainter cursorPainter){
|
public void addCursoPainter(CursorPainter cursorPainter){
|
||||||
painterList.add(cursorPainter);
|
painterList.add(cursorPainter);
|
||||||
cursorPainters.add(cursorPainter);
|
cursorPainters.add(cursorPainter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHighliteRelation(RelationType relationType){
|
public void setHighliteRelation(RelationType relationType){
|
||||||
if(arrowPainter!=null){
|
if(arrowPainter!=null){
|
||||||
boolean redraw = arrowPainter.getHighlightType()!=relationType;
|
boolean redraw = arrowPainter.getHighlightType()!=relationType;
|
||||||
arrowPainter.setHighlightType(relationType);
|
arrowPainter.setHighlightType(relationType);
|
||||||
if(redraw) redraw();
|
if(redraw) redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Point getOrigin() {
|
public Point getOrigin() {
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return getClientArea().width;
|
return getClientArea().width;
|
||||||
}
|
}
|
||||||
public void setOrigin(Point origin) {
|
public void setOrigin(Point origin) {
|
||||||
setOrigin(origin.x, origin.y);
|
setOrigin(origin.x, origin.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrigin(int x, int y) {
|
public void setOrigin(int x, int y) {
|
||||||
checkWidget();
|
checkWidget();
|
||||||
origin.x = x;
|
ScrollBar hBar = getHorizontalBar();
|
||||||
origin.y = y;
|
hBar.setSelection(-x);
|
||||||
syncSb();
|
x = -hBar.getSelection();
|
||||||
}
|
ScrollBar vBar = getVerticalBar();
|
||||||
|
vBar.setSelection(-y);
|
||||||
|
y = -vBar.getSelection();
|
||||||
|
origin.x = x;
|
||||||
|
origin.y = y;
|
||||||
|
syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
public long getMaxTime() {
|
||||||
public long getMaxTime() {
|
return maxTime;
|
||||||
return maxTime;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxTime(long maxTime) {
|
public void setMaxTime(long maxTime) {
|
||||||
this.maxTime = maxTime;
|
this.maxTime = maxTime;
|
||||||
if(maxTime>INITIAL_ZOOM_BAR_MAX) {
|
syncScrollBars();
|
||||||
long maxBarTime = maxTime;
|
}
|
||||||
while(maxBarTime>Integer.MAX_VALUE) maxBarTime/=1000;
|
|
||||||
horizontal.setMaximum((int) maxBarTime);
|
|
||||||
}
|
|
||||||
sliderScaleFactor = maxTime/horizontal.getMaximum();
|
|
||||||
syncSb();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public int getZoomLevel() {
|
||||||
public long getScale() {
|
return level;
|
||||||
return scaleFactor;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public int getMaxZoomLevel(){
|
||||||
public void setScale(long factor) {
|
return Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length-1;
|
||||||
setScalingFactor(factor, (getMaxVisibleTime()+getMinVisibleTime())/2);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public void setZoomLevel(int level) {
|
||||||
public void setVisibleRange(long startTime, long endTime) {
|
long tc=cursorPainters.get(0).getTime(); // cursor time
|
||||||
assert(startTime<endTime);
|
setZoomLevel(level, tc);
|
||||||
long time_diff = endTime-startTime;
|
}
|
||||||
long factor = (time_diff*11/10)/getClientArea().width;
|
|
||||||
setScalingFactor(factor, startTime+time_diff/2);
|
|
||||||
}
|
|
||||||
|
|
||||||
//@Override
|
public void setZoomLevel(int level, long centerTime) {
|
||||||
public void setScalingFactor(long factor, long centerTime) {
|
//FIXME: keep center if zoom-out and cursor is not in view
|
||||||
Rectangle clientArea = getClientArea();
|
if(level<0) level = 0;
|
||||||
long clientAreaWidth = clientArea.width;
|
long xc=centerTime/this.scaleFactor; // cursor total x-offset
|
||||||
long maxFactor=maxTime/clientAreaWidth;
|
if(level<Constants.UNIT_MULTIPLIER.length*Constants.UNIT_STRING.length){
|
||||||
if(factor<0) {
|
this.scaleFactor = (long) Math.pow(10, level>>1);
|
||||||
if(factor== ZOOM_FIT) {
|
if(level%2==1) this.scaleFactor*=3;
|
||||||
long cTime = getCursorPainters().get(0).getTime();
|
ITx tx = arrowPainter.getTx();
|
||||||
long time_diff = centerTime>cTime?centerTime-cTime:cTime-centerTime;
|
arrowPainter.setTx(null);
|
||||||
centerTime = (centerTime>cTime?cTime:centerTime)+time_diff/2;
|
/*
|
||||||
factor = (time_diff*11/10)/clientAreaWidth;
|
* xc = tc/oldScaleFactor
|
||||||
} else if(factor== ZOOM_FULL)
|
* xoffs = xc+origin.x
|
||||||
factor = maxFactor;
|
* xcn = tc/newScaleFactor
|
||||||
}
|
* t0n = (xcn-xoffs)*scaleFactor
|
||||||
if(factor==0)
|
*/
|
||||||
factor=1;
|
long xoffs=xc+origin.x; // cursor offset relative to left border
|
||||||
else if(factor>maxFactor)
|
long xcn=centerTime/scaleFactor; // new total x-offset
|
||||||
factor=maxFactor;
|
|
||||||
if(factor!=getScale() || (getMaxVisibleTime()+getMinVisibleTime()/2) != centerTime) {
|
|
||||||
updateScaleFactor(factor);
|
|
||||||
ITx tx = arrowPainter.getTx();
|
|
||||||
arrowPainter.setTx(null);
|
|
||||||
/*
|
|
||||||
* xc = tc/oldScaleFactor
|
|
||||||
* xoffs = xc+origin.x
|
|
||||||
* xcn = tc/newScaleFactor
|
|
||||||
* t0n = (xcn-xoffs)*getScale()
|
|
||||||
*/
|
|
||||||
long xoffs = clientAreaWidth/2;
|
|
||||||
long xcn=centerTime/getScale(); // new total x-offset
|
|
||||||
long originX=xcn-xoffs;
|
long originX=xcn-xoffs;
|
||||||
if(originX>0) {
|
if(originX>0) {
|
||||||
origin.x=(int) -originX; // new cursor time offset relative to left border
|
origin.x=(int) -originX; // new cursor time offset relative to left border
|
||||||
}else {
|
}else {
|
||||||
origin.x=0;
|
origin.x=0;
|
||||||
}
|
}
|
||||||
syncSb();
|
syncScrollBars();
|
||||||
arrowPainter.setTx(tx);
|
arrowPainter.setTx(tx);
|
||||||
redraw();
|
redraw();
|
||||||
}
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateScaleFactor(long factor) {
|
public long getScaleFactor() {
|
||||||
scaleFactor = factor;
|
return scaleFactor;
|
||||||
scaleMagnitude = 0;
|
}
|
||||||
for(int i=Constants.POWERS_OF_TEN.length-1; i>0; i--) {
|
|
||||||
if(scaleFactor>=Constants.POWERS_OF_TEN[i]) {
|
|
||||||
scaleMagnitude = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public long getScaleFactorPow10() {
|
||||||
public String timeToString(long time) {
|
int scale = level/Constants.UNIT_MULTIPLIER.length;
|
||||||
int idx = scaleMagnitude/3;
|
double res = Math.pow(1000, scale);
|
||||||
double fTime = (double)time/Constants.UNIT_MULTIPLIER[idx];
|
return (long) res;
|
||||||
return Constants.getTimeFormatForLevel(idx).format(fTime)+Constants.UNIT_STRING[idx];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimeForOffset(int xOffset){
|
public String getUnitStr(){
|
||||||
return (xOffset-origin.x) * getScale();
|
return Constants.UNIT_STRING[level/Constants.UNIT_MULTIPLIER.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPainter(IPainter painter) {
|
public int getUnitMultiplier(){
|
||||||
painterList.add(painter);
|
return Constants.UNIT_MULTIPLIER[level%Constants.UNIT_MULTIPLIER.length];
|
||||||
redraw();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void removePainter(IPainter painter) {
|
public long getTimeForOffset(int xOffset){
|
||||||
painterList.remove(painter);
|
return (xOffset-origin.x) * scaleFactor;
|
||||||
redraw();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void clearAllWaveformPainter() {
|
public void addPainter(IPainter painter) {
|
||||||
clearAllWaveformPainter(true);
|
painterList.add(painter);
|
||||||
}
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
void clearAllWaveformPainter(boolean update) {
|
public void removePainter(IPainter painter) {
|
||||||
trackAreaPainter.trackVerticalOffset.clear();
|
painterList.remove(painter);
|
||||||
wave2painterMap.clear();
|
redraw();
|
||||||
if(update) syncSb();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void addWaveformPainter(IWaveformPainter painter) {
|
public void clearAllWaveformPainter() {
|
||||||
addWaveformPainter(painter, true);
|
clearAllWaveformPainter(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addWaveformPainter(IWaveformPainter painter, boolean update) {
|
void clearAllWaveformPainter(boolean update) {
|
||||||
trackAreaPainter.addTrackPainter(painter);
|
trackAreaPainter.trackVerticalOffset.clear();
|
||||||
wave2painterMap.put(painter.getTrackEntry().waveform, painter);
|
wave2painterMap.clear();
|
||||||
if(update) syncSb();
|
if(update) syncScrollBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CursorPainter> getCursorPainters() {
|
public void addWaveformPainter(IWaveformPainter painter) {
|
||||||
|
addWaveformPainter(painter, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addWaveformPainter(IWaveformPainter painter, boolean update) {
|
||||||
|
trackAreaPainter.addTrackPainter(painter);
|
||||||
|
wave2painterMap.put(painter.getTrackEntry().waveform, painter);
|
||||||
|
if(update) syncScrollBars();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CursorPainter> getCursorPainters() {
|
||||||
return cursorPainters;
|
return cursorPainters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the scrollbar and register listeners. */
|
/* Initialize the scrollbar and register listeners. */
|
||||||
private void initScrollBars() {
|
private void initScrollBars() {
|
||||||
horizontal.setEnabled(false);
|
ScrollBar horizontal = getHorizontalBar();
|
||||||
horizontal.setVisible(true);
|
horizontal.setEnabled(false);
|
||||||
horizontal.addSelectionListener(new SelectionAdapter() {
|
horizontal.setVisible(true);
|
||||||
|
horizontal.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent event) {
|
public void widgetSelected(SelectionEvent event) {
|
||||||
if (!painterList.isEmpty()) {
|
if (painterList.isEmpty())
|
||||||
int[] sel = horizontal.getSelection();
|
return;
|
||||||
long lowerTime = sel[0]*sliderScaleFactor;
|
setOrigin(-((ScrollBar) event.widget).getSelection(), origin.y);
|
||||||
long upperTime = sel[1]*sliderScaleFactor;
|
}
|
||||||
if(sel[1]-sel[0] != lastHorSelection[1]-lastHorSelection[0]) {
|
});
|
||||||
long time_diff = upperTime-lowerTime;
|
ScrollBar vertical = getVerticalBar();
|
||||||
long factor = time_diff/getClientArea().width;
|
vertical.setEnabled(false);
|
||||||
setScalingFactor(factor, lowerTime+time_diff/2);
|
vertical.setVisible(true);
|
||||||
} else {
|
vertical.addSelectionListener(new SelectionAdapter() {
|
||||||
origin.x = -(int) (lowerTime/getScale());
|
|
||||||
WaveformCanvas.this.getDisplay().asyncExec(() -> {redraw();});
|
|
||||||
}
|
|
||||||
lastHorSelection=sel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
horizontal.setMinimum(0);
|
|
||||||
horizontal.setMaximum(INITIAL_ZOOM_BAR_MAX);
|
|
||||||
lastHorSelection = horizontal.getSelection();
|
|
||||||
|
|
||||||
vertical.setEnabled(false);
|
|
||||||
vertical.setVisible(true);
|
|
||||||
vertical.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent event) {
|
public void widgetSelected(SelectionEvent event) {
|
||||||
if (!painterList.isEmpty()) {
|
if (painterList.isEmpty())
|
||||||
origin.y=-vertical.getSelection();
|
return;
|
||||||
fireSelectionEvent();
|
setOrigin(origin.x, -((ScrollBar) event.widget).getSelection());
|
||||||
WaveformCanvas.this.getDisplay().asyncExec(() -> {redraw();});
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronize the scrollbar with the image. If the transform is out of
|
* Synchronize the scrollbar with the image. If the transform is out of
|
||||||
* range, it will correct it. This function considers only following factors
|
* range, it will correct it. This function considers only following factors
|
||||||
* :<b> transform, image size, client area</b>.
|
* :<b> transform, image size, client area</b>.
|
||||||
*/
|
*/
|
||||||
public void syncSb() {
|
public void syncScrollBars() {
|
||||||
if (!painterList.isEmpty()) {
|
if (painterList.isEmpty()) {
|
||||||
syncHSb();
|
redraw();
|
||||||
syncVSb();
|
return;
|
||||||
fireSelectionEvent();
|
}
|
||||||
}
|
int height = trackAreaPainter.getHeight(); // incl. Ruler
|
||||||
redraw();
|
long width = maxTime / scaleFactor;
|
||||||
}
|
Rectangle clientArea=getClientArea();
|
||||||
|
ScrollBar horizontal = getHorizontalBar();
|
||||||
|
horizontal.setIncrement(getClientArea().width / 100);
|
||||||
|
horizontal.setPageIncrement(getClientArea().width);
|
||||||
|
int clientWidthw = clientArea.width;
|
||||||
|
if (width > clientWidthw) { /* image is wider than client area */
|
||||||
|
horizontal.setMinimum(0);
|
||||||
|
horizontal.setMaximum((int)width);
|
||||||
|
horizontal.setEnabled(true);
|
||||||
|
if (-origin.x > horizontal.getMaximum() - clientWidthw) {
|
||||||
|
origin.x = -horizontal.getMaximum() + clientWidthw;
|
||||||
|
}
|
||||||
|
} else { /* image is narrower than client area */
|
||||||
|
horizontal.setEnabled(false);
|
||||||
|
}
|
||||||
|
horizontal.setThumb(clientWidthw);
|
||||||
|
horizontal.setSelection(-origin.x);
|
||||||
|
|
||||||
private void syncVSb() {
|
ScrollBar vertical = getVerticalBar();
|
||||||
Rectangle clientArea=getClientArea();
|
vertical.setIncrement(getClientArea().height / 100);
|
||||||
int height = trackAreaPainter.getHeight(); // incl. Ruler
|
vertical.setPageIncrement(getClientArea().height);
|
||||||
int clientHeight = clientArea.height;
|
int clientHeighth = clientArea.height;
|
||||||
vertical.setIncrement(clientHeight / 100);
|
if (height > clientHeighth) { /* image is higher than client area */
|
||||||
vertical.setPageIncrement(clientHeight/2);
|
vertical.setMinimum(0);
|
||||||
if (height > clientHeight) { /* image is higher than client area */
|
vertical.setMaximum(height);
|
||||||
vertical.setMinimum(0);
|
vertical.setEnabled(true);
|
||||||
vertical.setMaximum(height);
|
if ( -origin.y > vertical.getMaximum() - clientHeighth) {
|
||||||
vertical.setEnabled(true);
|
origin.y = -vertical.getMaximum() + clientHeighth;
|
||||||
if ( -origin.y > vertical.getMaximum() - clientHeight) {
|
}
|
||||||
origin.y = -vertical.getMaximum() + clientHeight;
|
} else { /* image is less higher than client area */
|
||||||
}
|
vertical.setMaximum(clientHeighth);
|
||||||
} else { /* image is less higher than client area */
|
vertical.setEnabled(false);
|
||||||
vertical.setMaximum(clientHeight);
|
}
|
||||||
vertical.setEnabled(false);
|
vertical.setThumb(clientHeighth);
|
||||||
}
|
vertical.setSelection(-origin.y);
|
||||||
vertical.setThumb(clientHeight);
|
redraw();
|
||||||
vertical.setSelection(-origin.y);
|
fireSelectionEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncHSb() {
|
/* Paint function */
|
||||||
horizontal.setEnabled(wave2painterMap.size()>0);
|
private void paint(GC gc) {
|
||||||
Rectangle clientArea=getClientArea();
|
Point pt = getSize();
|
||||||
int clientWidth = clientArea.width;
|
if(pt.x==0 || pt.y==0) return;
|
||||||
if(sliderScaleFactor>0) {
|
Rectangle clientRect = getClientArea(); /* Canvas' painting area */
|
||||||
int lower = (int) ( ( -origin.x * getScale()) / sliderScaleFactor);
|
GC thisGc = gc;
|
||||||
int upper = (int) (((clientWidth-origin.x) * getScale()) / sliderScaleFactor);
|
Image dBackingImg = null;
|
||||||
lastHorSelection = new int[] {Math.max(lower,0), Math.min(upper, horizontal.getMaximum())};
|
if(doubleBuffering) {
|
||||||
horizontal.setSelection(lastHorSelection);
|
dBackingImg = new Image(getDisplay(), pt.x, pt.y);
|
||||||
}
|
thisGc = new GC(dBackingImg);
|
||||||
long width = maxTime / getScale();
|
thisGc.setBackground(gc.getBackground());
|
||||||
horizontal.setButtonsEnabled(width > clientWidth);
|
thisGc.setForeground(gc.getForeground());
|
||||||
}
|
thisGc.setFont(gc.getFont());
|
||||||
|
|
||||||
/* Paint function */
|
}
|
||||||
private void paint(GC gc) {
|
Projection p = new Projection(thisGc);
|
||||||
Point pt = getSize();
|
p.setTranslation(origin);
|
||||||
if(pt.x==0 || pt.y==0) return;
|
if (!painterList.isEmpty() ) {
|
||||||
Rectangle clientRect = getClientArea(); /* Canvas' painting area */
|
for (IPainter painter : painterList)
|
||||||
GC thisGc = gc;
|
painter.paintArea(p, clientRect);
|
||||||
Image dBackingImg = null;
|
} else {
|
||||||
if(doubleBuffering) {
|
gc.fillRectangle(clientRect);
|
||||||
dBackingImg = new Image(getDisplay(), pt.x, pt.y);
|
initScrollBars();
|
||||||
thisGc = new GC(dBackingImg);
|
}
|
||||||
thisGc.setBackground(gc.getBackground());
|
if(doubleBuffering) {
|
||||||
thisGc.setForeground(gc.getForeground());
|
gc.drawImage(dBackingImg, 0, 0);
|
||||||
thisGc.setFont(gc.getFont());
|
if(dBackingImg!=null) dBackingImg.dispose();
|
||||||
|
thisGc.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
public List<Object> getElementsAt(Point point) {
|
||||||
Projection p = new Projection(thisGc);
|
LinkedList<Object> result=new LinkedList<>();
|
||||||
p.setTranslation(origin);
|
for (IPainter p : Lists.reverse(painterList)) {
|
||||||
if (!painterList.isEmpty() ) {
|
if (p instanceof TrackAreaPainter) {
|
||||||
for (IPainter painter : painterList)
|
int y = point.y - origin.y;
|
||||||
painter.paintArea(p, clientRect);
|
int x = point.x - origin.x;
|
||||||
} else {
|
Entry<Integer, IWaveformPainter> entry = trackAreaPainter.trackVerticalOffset.floorEntry(y);
|
||||||
gc.fillRectangle(clientRect);
|
if (entry != null) {
|
||||||
initScrollBars();
|
if (entry.getValue() instanceof StreamPainter) {
|
||||||
}
|
ITx tx = ((StreamPainter) entry.getValue()).getClicked(new Point(x, y - entry.getKey()));
|
||||||
if(doubleBuffering) {
|
if(tx!=null)
|
||||||
gc.drawImage(dBackingImg, 0, 0);
|
result.add(tx);
|
||||||
if(dBackingImg!=null) dBackingImg.dispose();
|
}
|
||||||
thisGc.dispose();
|
result.add(entry.getValue().getTrackEntry());
|
||||||
}
|
}
|
||||||
}
|
} else if (p instanceof CursorPainter) {
|
||||||
|
if (Math.abs(point.x - origin.x - ((CursorPainter) p).getTime()/scaleFactor) < 2) {
|
||||||
|
result.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Object> getElementsAt(Point point) {
|
public List<Object> getEntriesAtPosition(IWaveform iWaveform, int i) {
|
||||||
LinkedList<Object> result=new LinkedList<>();
|
LinkedList<Object> result=new LinkedList<>();
|
||||||
for (IPainter p : Lists.reverse(painterList)) {
|
int x = i - origin.x;
|
||||||
if (p instanceof TrackAreaPainter) {
|
for(IWaveformPainter p: wave2painterMap.values()){
|
||||||
int y = point.y - origin.y;
|
if (p instanceof StreamPainter && ((StreamPainter)p).getStream()==iWaveform) {
|
||||||
int x = point.x - origin.x;
|
result.add(((StreamPainter) p).getClicked(new Point(x, styleProvider.getTrackHeight()/2)));
|
||||||
Entry<Integer, IWaveformPainter> entry = trackAreaPainter.trackVerticalOffset.floorEntry(y);
|
}
|
||||||
if (entry != null) {
|
}
|
||||||
if (entry.getValue() instanceof StreamPainter) {
|
return result;
|
||||||
ITx tx = ((StreamPainter) entry.getValue()).getClicked(new Point(x, y - entry.getKey()));
|
}
|
||||||
if(tx!=null)
|
|
||||||
result.add(tx);
|
|
||||||
}
|
|
||||||
result.add(entry.getValue().getTrackEntry());
|
|
||||||
}
|
|
||||||
} else if (p instanceof CursorPainter) {
|
|
||||||
if (Math.abs(point.x - origin.x - ((CursorPainter) p).getTime()/getScale()) < 2) {
|
|
||||||
result.add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Object> getEntriesAtPosition(IWaveform iWaveform, int i) {
|
public void setSelected(ITx currentSelection) {
|
||||||
LinkedList<Object> result=new LinkedList<>();
|
this.currentSelection = currentSelection;
|
||||||
int x = i - origin.x;
|
if (currentSelection != null)
|
||||||
for(IWaveformPainter p: wave2painterMap.values()){
|
reveal(currentSelection);
|
||||||
if (p instanceof StreamPainter && ((StreamPainter)p).getStream()==iWaveform) {
|
arrowPainter.setTx(currentSelection);
|
||||||
result.add(((StreamPainter) p).getClicked(new Point(x, styleProvider.getTrackHeight()/2)));
|
redraw();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelected(ITx currentSelection) {
|
public void reveal(ITx tx) {
|
||||||
this.currentSelection = currentSelection;
|
int lower = (int) (tx.getBeginTime() / scaleFactor);
|
||||||
if (currentSelection != null)
|
int higher = (int) (tx.getEndTime() / scaleFactor);
|
||||||
reveal(currentSelection);
|
Point size = getSize();
|
||||||
arrowPainter.setTx(currentSelection);
|
size.x -= getVerticalBar().getSize().x + 2;
|
||||||
redraw();
|
size.y -= getHorizontalBar().getSize().y;
|
||||||
}
|
if (lower < -origin.x) {
|
||||||
|
setOrigin(-lower, origin.y);
|
||||||
public void reveal(ITx tx) {
|
} else if (higher > (size.x - origin.x)) {
|
||||||
int lower = (int) (tx.getBeginTime() / getScale());
|
setOrigin(size.x - higher, origin.y);
|
||||||
int higher = (int) (tx.getEndTime() / getScale());
|
}
|
||||||
Point size = getSize();
|
for (IWaveformPainter painter : wave2painterMap.values()) {
|
||||||
size.x -= vertical.getSize().x + 2;
|
if (painter instanceof StreamPainter && ((StreamPainter) painter).getStream() == tx.getStream()) {
|
||||||
size.y -= horizontal.getSize().y;
|
EventEntry entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime());
|
||||||
if (lower < -origin.x) {
|
Optional<IEvent> res = Arrays.stream(entry.events).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst();
|
||||||
setOrigin(-lower, origin.y);
|
if(res.isPresent()) {
|
||||||
} else if (higher > (size.x - origin.x)) {
|
int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * ((ITxEvent)res.get()).getRowIndex();
|
||||||
setOrigin(size.x - higher, origin.y);
|
int bottom = top + styleProvider.getTrackHeight();
|
||||||
}
|
if (top < -origin.y) {
|
||||||
for (IWaveformPainter painter : wave2painterMap.values()) {
|
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
|
||||||
if (painter instanceof StreamPainter && ((StreamPainter) painter).getStream() == tx.getStream()) {
|
} else if (bottom > (size.y - origin.y)) {
|
||||||
EventEntry entry = tx.getStream().getEvents().floorEntry(tx.getBeginTime());
|
setOrigin(origin.x, size.y - bottom);
|
||||||
Optional<IEvent> res = Arrays.stream(entry.events).filter(e -> ((ITxEvent)e).getTransaction().equals(tx)).findFirst();
|
}
|
||||||
if(res.isPresent()) {
|
}
|
||||||
int top = painter.getVerticalOffset() + styleProvider.getTrackHeight() * ((ITxEvent)res.get()).getRowIndex();
|
}
|
||||||
int bottom = top + styleProvider.getTrackHeight();
|
}
|
||||||
if (top < -origin.y) {
|
}
|
||||||
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
|
|
||||||
} else if (bottom > (size.y - origin.y)) {
|
|
||||||
setOrigin(origin.x, size.y - bottom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reveal(IWaveform waveform) {
|
public void reveal(IWaveform waveform) {
|
||||||
for (IWaveformPainter painter : wave2painterMap.values()) {
|
for (IWaveformPainter painter : wave2painterMap.values()) {
|
||||||
TrackEntry te = painter.getTrackEntry();
|
TrackEntry te = painter.getTrackEntry();
|
||||||
if(te.waveform == waveform) {
|
if(te.waveform == waveform) {
|
||||||
Point size = getSize();
|
Point size = getSize();
|
||||||
size.y -=+rulerHeight;
|
size.y -=+rulerHeight;
|
||||||
if((horizontal.getStyle()&SWT.SCROLLBAR_OVERLAY)!=0 && horizontal.isVisible())
|
ScrollBar sb = getHorizontalBar();
|
||||||
size.y-= horizontal.getSize().y;
|
if((sb.getStyle()&SWT.SCROLLBAR_OVERLAY)!=0 && sb.isVisible())
|
||||||
int top = te.vOffset;
|
size.y-= getHorizontalBar().getSize().y;
|
||||||
int bottom = top + styleProvider.getTrackHeight();
|
int top = te.vOffset;
|
||||||
if (top < -origin.y) {
|
int bottom = top + styleProvider.getTrackHeight();
|
||||||
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
|
if (top < -origin.y) {
|
||||||
} else if (bottom > (size.y - origin.y)) {
|
setOrigin(origin.x, -(top-styleProvider.getTrackHeight()));
|
||||||
setOrigin(origin.x, size.y - bottom);
|
} else if (bottom > (size.y - origin.y)) {
|
||||||
}
|
setOrigin(origin.x, size.y - bottom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reveal(long time) {
|
public void reveal(long time) {
|
||||||
int scaledTime = (int) (time / getScale());
|
int scaledTime = (int) (time / scaleFactor);
|
||||||
Point size = getSize();
|
Point size = getSize();
|
||||||
size.x -= vertical.getSize().x + 2;
|
size.x -= getVerticalBar().getSize().x + 2;
|
||||||
size.y -= horizontal.getSize().y;
|
size.y -= getHorizontalBar().getSize().y;
|
||||||
if (scaledTime < -origin.x) {
|
if (scaledTime < -origin.x) {
|
||||||
setOrigin(-scaledTime+10, origin.y);
|
setOrigin(-scaledTime+10, origin.y);
|
||||||
} else if (scaledTime > (size.x - origin.x)) {
|
} else if (scaledTime > (size.x - origin.x)) {
|
||||||
setOrigin(size.x - scaledTime-30, origin.y);
|
setOrigin(size.x - scaledTime-30, origin.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public int getRulerHeight() {
|
||||||
public void centerAt(long time) {
|
return rulerHeight;
|
||||||
int scaledTime = (int) (time / getScale());
|
}
|
||||||
int newX = -scaledTime+getWidth()/2;
|
|
||||||
setOrigin(newX>0?0:newX, origin.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRulerHeight() {
|
public void setRulerHeight(int rulerHeight) {
|
||||||
return rulerHeight;
|
this.rulerHeight = rulerHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRulerHeight(int rulerHeight) {
|
public void addSelectionListener(SelectionAdapter selectionAdapter) {
|
||||||
this.rulerHeight = rulerHeight;
|
selectionListeners.add(selectionAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSelectionListener(SelectionAdapter selectionAdapter) {
|
public void removeSelectionListener(SelectionAdapter selectionAdapter) {
|
||||||
selectionListeners.add(selectionAdapter);
|
selectionListeners.remove(selectionAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeSelectionListener(SelectionAdapter selectionAdapter) {
|
/**
|
||||||
selectionListeners.remove(selectionAdapter);
|
*
|
||||||
}
|
*/
|
||||||
|
protected void fireSelectionEvent() {
|
||||||
|
Event e = new Event();
|
||||||
|
e.widget = this;
|
||||||
|
e.detail=SWT.SELECTED;
|
||||||
|
e.type=SWT.Selection;
|
||||||
|
SelectionEvent ev = new SelectionEvent(e);
|
||||||
|
ev.x = origin.x;
|
||||||
|
ev.y = origin.y;
|
||||||
|
for (SelectionAdapter a : selectionListeners) {
|
||||||
|
a.widgetSelected(ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
long getMaxVisibleTime() {
|
||||||
*
|
return (getClientArea().width+origin.x)*scaleFactor;
|
||||||
*/
|
}
|
||||||
protected void fireSelectionEvent() {
|
|
||||||
Event e = new Event();
|
|
||||||
e.widget = this;
|
|
||||||
e.detail=SWT.SELECTED;
|
|
||||||
e.type=SWT.Selection;
|
|
||||||
SelectionEvent ev = new SelectionEvent(e);
|
|
||||||
ev.x = origin.x;
|
|
||||||
ev.y = origin.y;
|
|
||||||
for (SelectionAdapter a : selectionListeners) {
|
|
||||||
a.widgetSelected(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
long getMinVisibleTime() {
|
||||||
@Override
|
return origin.x * scaleFactor;
|
||||||
public long getMaxVisibleTime() {
|
}
|
||||||
return (getClientArea().width-origin.x)*getScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getMinVisibleTime() {
|
|
||||||
return -origin.x * getScale();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMinVisibleTime(long time) {
|
|
||||||
long duration = getMaxVisibleTime()-getMinVisibleTime();
|
|
||||||
if(time>0) {
|
|
||||||
if((time+duration)<getMaxTime()) {
|
|
||||||
int scaledTime = (int) (time / getScale());
|
|
||||||
setOrigin(-scaledTime, origin.y);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setOrigin(0, origin.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void zoom(ZoomKind kind) {
|
|
||||||
switch(kind) {
|
|
||||||
case IN:
|
|
||||||
setScale(getScale()/2);
|
|
||||||
break;
|
|
||||||
case OUT:
|
|
||||||
setScale(getScale()*2);
|
|
||||||
break;
|
|
||||||
case FIT:
|
|
||||||
setScalingFactor(WaveformCanvas.ZOOM_FIT, cursorPainters.get(1).getTime());
|
|
||||||
break;
|
|
||||||
case FULL:
|
|
||||||
setScale(WaveformCanvas.ZOOM_FULL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStyleProvider(IWaveformStyleProvider styleProvider) {
|
public void setStyleProvider(IWaveformStyleProvider styleProvider) {
|
||||||
this.styleProvider=styleProvider;
|
this.styleProvider=styleProvider;
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getScaleMagnitude() {
|
|
||||||
return scaleMagnitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ package com.minres.scviewer.database.ui.swt.internal;
|
|||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.beans.PropertyChangeSupport;
|
import java.beans.PropertyChangeSupport;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -89,9 +90,8 @@ import com.minres.scviewer.database.ui.GotoDirection;
|
|||||||
import com.minres.scviewer.database.ui.ICursor;
|
import com.minres.scviewer.database.ui.ICursor;
|
||||||
import com.minres.scviewer.database.ui.IWaveformStyleProvider;
|
import com.minres.scviewer.database.ui.IWaveformStyleProvider;
|
||||||
import com.minres.scviewer.database.ui.IWaveformView;
|
import com.minres.scviewer.database.ui.IWaveformView;
|
||||||
import com.minres.scviewer.database.ui.IWaveformZoom;
|
|
||||||
import com.minres.scviewer.database.ui.TrackEntry;
|
import com.minres.scviewer.database.ui.TrackEntry;
|
||||||
import com.minres.scviewer.database.ui.swt.internal.slider.ZoomBar;
|
import com.minres.scviewer.database.ui.swt.Constants;
|
||||||
|
|
||||||
public class WaveformView implements IWaveformView {
|
public class WaveformView implements IWaveformView {
|
||||||
|
|
||||||
@ -99,6 +99,8 @@ public class WaveformView implements IWaveformView {
|
|||||||
|
|
||||||
private PropertyChangeSupport pcs;
|
private PropertyChangeSupport pcs;
|
||||||
|
|
||||||
|
static final DecimalFormat df = new DecimalFormat("#0.00####");
|
||||||
|
|
||||||
private ITx currentTxSelection;
|
private ITx currentTxSelection;
|
||||||
|
|
||||||
private ArrayList<TrackEntry> currentWaveformSelection = new ArrayList<>();
|
private ArrayList<TrackEntry> currentWaveformSelection = new ArrayList<>();
|
||||||
@ -113,10 +115,6 @@ public class WaveformView implements IWaveformView {
|
|||||||
|
|
||||||
private final Canvas valueList;
|
private final Canvas valueList;
|
||||||
|
|
||||||
private final Control nameFill;
|
|
||||||
|
|
||||||
private final Control valueFill;
|
|
||||||
|
|
||||||
final WaveformCanvas waveformCanvas;
|
final WaveformCanvas waveformCanvas;
|
||||||
|
|
||||||
final ToolTipHandler toolTipHandler;
|
final ToolTipHandler toolTipHandler;
|
||||||
@ -165,7 +163,8 @@ public class WaveformView implements IWaveformView {
|
|||||||
: streams.subList(firstIdx, lastIdx + 1);
|
: streams.subList(firstIdx, lastIdx + 1);
|
||||||
setSelection(new StructuredSelection(res), (e.stateMask & SWT.CTRL) != 0, false);
|
setSelection(new StructuredSelection(res), (e.stateMask & SWT.CTRL) != 0, false);
|
||||||
} else
|
} else
|
||||||
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false);
|
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0,
|
||||||
|
false);
|
||||||
} else {
|
} else {
|
||||||
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false);
|
setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false);
|
||||||
}
|
}
|
||||||
@ -198,45 +197,64 @@ public class WaveformView implements IWaveformView {
|
|||||||
down = false;
|
down = false;
|
||||||
if (start == null)
|
if (start == null)
|
||||||
return;
|
return;
|
||||||
if ((e.stateMask & SWT.MODIFIER_MASK & ~(SWT.SHIFT | SWT.CTRL)) != 0)
|
if ((e.stateMask & SWT.MODIFIER_MASK & ~SWT.SHIFT) != 0)
|
||||||
return; // don't react on modifier except shift and control
|
return; // don't react on modifier except shift
|
||||||
boolean isCtrl = (e.stateMask & SWT.CTRL)!=0;
|
if (e.button == 1 && Math.abs(e.x - start.x) > 3) {
|
||||||
boolean isShift = (e.stateMask & SWT.SHIFT)!=0;
|
asyncUpdate(e.widget);
|
||||||
if (e.button == 1) {
|
long startTime = waveformCanvas.getTimeForOffset(start.x);
|
||||||
if (Math.abs(e.x - start.x) > 3) { // was drag event
|
long endTime = waveformCanvas.getTimeForOffset(end.x);
|
||||||
asyncUpdate(e.widget);
|
long targetTimeRange = endTime - startTime;
|
||||||
long startTime = waveformCanvas.getTimeForOffset(start.x);
|
long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime();
|
||||||
long endTime = waveformCanvas.getTimeForOffset(end.x);
|
if (targetTimeRange == 0)
|
||||||
if(startTime<endTime) {
|
return;
|
||||||
waveformCanvas.setVisibleRange(startTime, endTime);
|
long relation = currentTimeRange / targetTimeRange;
|
||||||
} else if(start.x!=end.x){
|
long i = 1;
|
||||||
long targetTimeRange = startTime-endTime;
|
int level = 0;
|
||||||
long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime();
|
do {
|
||||||
long factor = currentTimeRange/targetTimeRange *waveformCanvas.getScale();
|
if (relation < 0) {
|
||||||
waveformCanvas.setScalingFactor(factor, (startTime+endTime)/2);
|
if (-relation < i) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if( isShift) { // set marker (button 1 and shift)
|
level--;
|
||||||
setMarkerTime(selectedMarker, snapOffsetToEvent(start));
|
if (-relation < i * 3) {
|
||||||
} else if(isCtrl) { // set cursor (button 1 and ctrl)
|
break;
|
||||||
setCursorTime(snapOffsetToEvent(start));
|
}
|
||||||
} else { // set cursor (button 1 only)
|
level--;
|
||||||
if (Math.abs(e.y - start.y) < 3) {
|
} else {
|
||||||
// first set cursor time
|
if (relation < i) {
|
||||||
setCursorTime(snapOffsetToEvent(start));
|
break;
|
||||||
// then set selection and reveal
|
}
|
||||||
setSelection(new StructuredSelection(initialSelected));
|
level++;
|
||||||
|
if (relation < i * 3) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
level++;
|
||||||
}
|
}
|
||||||
|
i = i * 10;
|
||||||
|
} while (i < 10000);
|
||||||
|
if (i < 10000) {
|
||||||
|
int curLevel = waveformCanvas.getZoomLevel();
|
||||||
|
waveformCanvas.setZoomLevel(curLevel - level, (startTime + endTime) / 2);
|
||||||
}
|
}
|
||||||
} else if (e.button == 2) { // set marker (button 2)
|
} else if (e.button == 1 && ((e.stateMask & SWT.SHIFT) == 0)) {
|
||||||
setMarkerTime(selectedMarker, snapOffsetToEvent(start));
|
// set cursor (button 1 and no shift)
|
||||||
|
if (Math.abs(e.x - start.x) < 3 && Math.abs(e.y - start.y) < 3) {
|
||||||
|
// first set cursor time
|
||||||
|
setCursorTime(snapOffsetToEvent(start));
|
||||||
|
// then set selection and reveal
|
||||||
|
setSelection(new StructuredSelection(initialSelected));
|
||||||
|
asyncUpdate(e.widget);
|
||||||
|
}
|
||||||
|
} else if (e.button == 2 || (e.button == 1 && (e.stateMask & SWT.SHIFT) != 0)) {
|
||||||
|
// set marker (button 1 and shift)
|
||||||
|
setMarkerTime(snapOffsetToEvent(start), selectedMarker);
|
||||||
|
asyncUpdate(e.widget);
|
||||||
}
|
}
|
||||||
asyncUpdate(e.widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long snapOffsetToEvent(Point p) {
|
protected long snapOffsetToEvent(Point p) {
|
||||||
long time = waveformCanvas.getTimeForOffset(p.x);
|
long time = waveformCanvas.getTimeForOffset(p.x);
|
||||||
long scaling = 5 * waveformCanvas.getScale();
|
long scaling = 5 * waveformCanvas.getScaleFactor();
|
||||||
for (Object o : waveformCanvas.getElementsAt(p)) {
|
for (Object o : waveformCanvas.getElementsAt(p)) {
|
||||||
EventEntry floorEntry = null;
|
EventEntry floorEntry = null;
|
||||||
EventEntry ceilEntry = null;
|
EventEntry ceilEntry = null;
|
||||||
@ -270,25 +288,6 @@ public class WaveformView implements IWaveformView {
|
|||||||
public void handleEvent(Event e) {
|
public void handleEvent(Event e) {
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
case SWT.MouseWheel:
|
case SWT.MouseWheel:
|
||||||
if((e.stateMask & SWT.CTRL) != 0) {
|
|
||||||
if(e.count<0) // up scroll
|
|
||||||
waveformCanvas.setScale(waveformCanvas.getScale()*11/10);
|
|
||||||
else // down scroll
|
|
||||||
waveformCanvas.setScale(waveformCanvas.getScale()*10/11);
|
|
||||||
e.doit=false;
|
|
||||||
} else if((e.stateMask & SWT.SHIFT) != 0) {
|
|
||||||
long upper = waveformCanvas.getMaxVisibleTime();
|
|
||||||
long lower = waveformCanvas.getMinVisibleTime();
|
|
||||||
long duration = upper-lower;
|
|
||||||
if(e.count<0) { // up scroll
|
|
||||||
long newLower = Math.min(waveformCanvas.getMaxTime()-duration, lower+duration/10);
|
|
||||||
waveformCanvas.setMinVisibleTime(newLower);
|
|
||||||
} else {// down scroll
|
|
||||||
long newLower = Math.max(0, lower-duration/10);
|
|
||||||
waveformCanvas.setMinVisibleTime(newLower);
|
|
||||||
}
|
|
||||||
e.doit=false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case SWT.MouseDown:
|
case SWT.MouseDown:
|
||||||
start = new Point(e.x, e.y);
|
start = new Point(e.x, e.y);
|
||||||
@ -348,25 +347,7 @@ public class WaveformView implements IWaveformView {
|
|||||||
rightSash.setBackground(SWTResourceManager.getColor(SWT.COLOR_GRAY));
|
rightSash.setBackground(SWTResourceManager.getColor(SWT.COLOR_GRAY));
|
||||||
|
|
||||||
Composite valuePane = new Composite(rightSash, SWT.NONE);
|
Composite valuePane = new Composite(rightSash, SWT.NONE);
|
||||||
|
waveformCanvas = new WaveformCanvas(rightSash, SWT.NONE, styleProvider);
|
||||||
Composite waveformPane = new Composite(rightSash, SWT.NONE);
|
|
||||||
GridLayout gl_waveformPane = new GridLayout(1, false);
|
|
||||||
gl_waveformPane.verticalSpacing = 0;
|
|
||||||
gl_waveformPane.marginWidth = 0;
|
|
||||||
gl_waveformPane.marginHeight = 0;
|
|
||||||
waveformPane.setLayout(gl_waveformPane);
|
|
||||||
|
|
||||||
waveformCanvas = new WaveformCanvas(waveformPane, SWT.NONE | SWT.V_SCROLL /*| SWT.H_SCROLL*/, styleProvider, new ZoomBar.IProvider() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ZoomBar getScrollBar() {
|
|
||||||
ZoomBar timeSliderPane = new ZoomBar(waveformPane, SWT.NONE);
|
|
||||||
GridData gd_timeSliderPane = new GridData(SWT.FILL, SWT.BOTTOM, false, false, 1, 1);
|
|
||||||
timeSliderPane.setLayoutData(gd_timeSliderPane);
|
|
||||||
return timeSliderPane;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
waveformCanvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
|
|
||||||
|
|
||||||
// create the name pane
|
// create the name pane
|
||||||
createTextPane(namePane, "Name");
|
createTextPane(namePane, "Name");
|
||||||
@ -383,10 +364,7 @@ public class WaveformView implements IWaveformView {
|
|||||||
@Override
|
@Override
|
||||||
public void controlResized(ControlEvent e) {
|
public void controlResized(ControlEvent e) {
|
||||||
nameListScrolled.getVerticalBar().setVisible(false);
|
nameListScrolled.getVerticalBar().setVisible(false);
|
||||||
if(nameListScrolled.getSize().y == nameList.getSize().y) {
|
|
||||||
((GridData)nameFill.getLayoutData()).heightHint=18;
|
|
||||||
namePane.layout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
nameList = new Canvas(nameListScrolled, SWT.NONE) {
|
nameList = new Canvas(nameListScrolled, SWT.NONE) {
|
||||||
@ -405,7 +383,6 @@ public class WaveformView implements IWaveformView {
|
|||||||
});
|
});
|
||||||
nameList.addMouseListener(nameValueMouseListener);
|
nameList.addMouseListener(nameValueMouseListener);
|
||||||
nameListScrolled.setContent(nameList);
|
nameListScrolled.setContent(nameList);
|
||||||
nameFill = createFill(namePane);
|
|
||||||
|
|
||||||
createTextPane(valuePane, "Value");
|
createTextPane(valuePane, "Value");
|
||||||
|
|
||||||
@ -419,10 +396,7 @@ public class WaveformView implements IWaveformView {
|
|||||||
@Override
|
@Override
|
||||||
public void controlResized(ControlEvent e) {
|
public void controlResized(ControlEvent e) {
|
||||||
valueListScrolled.getVerticalBar().setVisible(false);
|
valueListScrolled.getVerticalBar().setVisible(false);
|
||||||
if(valueListScrolled.getSize().y == valueList.getSize().y) {
|
|
||||||
((GridData)valueFill.getLayoutData()).heightHint=18;
|
|
||||||
valuePane.layout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
valueList = new Canvas(valueListScrolled, SWT.NONE) {
|
valueList = new Canvas(valueListScrolled, SWT.NONE) {
|
||||||
@ -441,7 +415,6 @@ public class WaveformView implements IWaveformView {
|
|||||||
});
|
});
|
||||||
valueList.addMouseListener(nameValueMouseListener);
|
valueList.addMouseListener(nameValueMouseListener);
|
||||||
valueListScrolled.setContent(valueList);
|
valueListScrolled.setContent(valueList);
|
||||||
valueFill = createFill(valuePane);
|
|
||||||
|
|
||||||
waveformCanvas.setMaxTime(1);
|
waveformCanvas.setMaxTime(1);
|
||||||
waveformCanvas.addPaintListener(waveformMouseListener);
|
waveformCanvas.addPaintListener(waveformMouseListener);
|
||||||
@ -488,26 +461,6 @@ public class WaveformView implements IWaveformView {
|
|||||||
|
|
||||||
toolTipHandler = new ToolTipHandler(parent.getShell());
|
toolTipHandler = new ToolTipHandler(parent.getShell());
|
||||||
toolTipHandler.activateHoverHelp(waveformCanvas);
|
toolTipHandler.activateHoverHelp(waveformCanvas);
|
||||||
// This is the filter that prevents the default handling of mouse wheel in waveformCanvas
|
|
||||||
getControl().getDisplay().addFilter(SWT.MouseWheel, new Listener() {
|
|
||||||
@Override
|
|
||||||
public void handleEvent(Event e) {
|
|
||||||
// Check if it's the correct widget
|
|
||||||
if(e.widget.equals(waveformCanvas) && (e.stateMask & SWT.CTRL) != 0) {
|
|
||||||
waveformMouseListener.handleEvent(e);
|
|
||||||
e.doit = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private Control createFill(Composite pane) {
|
|
||||||
Label cLabel = new Label(pane, SWT.NONE);
|
|
||||||
cLabel.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_BACKGROUND));
|
|
||||||
GridData gd_cLabel = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
|
|
||||||
gd_cLabel.heightHint = 0;
|
|
||||||
cLabel.setLayoutData(gd_cLabel);
|
|
||||||
return cLabel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTextPane(Composite namePane, String text) {
|
private void createTextPane(Composite namePane, String text) {
|
||||||
@ -575,7 +528,7 @@ public class WaveformView implements IWaveformView {
|
|||||||
tracksVerticalHeight += streamEntry.height;
|
tracksVerticalHeight += streamEntry.height;
|
||||||
even = !even;
|
even = !even;
|
||||||
}
|
}
|
||||||
waveformCanvas.syncSb();
|
waveformCanvas.syncScrollBars();
|
||||||
nameList.setSize(nameMaxWidth + 15, tracksVerticalHeight);
|
nameList.setSize(nameMaxWidth + 15, tracksVerticalHeight);
|
||||||
nameListScrolled.setMinSize(nameMaxWidth + 15, tracksVerticalHeight);
|
nameListScrolled.setMinSize(nameMaxWidth + 15, tracksVerticalHeight);
|
||||||
nameList.redraw();
|
nameList.redraw();
|
||||||
@ -799,30 +752,27 @@ public class WaveformView implements IWaveformView {
|
|||||||
if (!add)
|
if (!add)
|
||||||
currentWaveformSelection.clear();
|
currentWaveformSelection.clear();
|
||||||
List<?> selList = sel.toList();
|
List<?> selList = sel.toList();
|
||||||
for(Object o: selList) {
|
if (selList.get(0) instanceof ITx) {
|
||||||
if (o instanceof ITx) {
|
ITx txSel = (ITx) selList.get(0);
|
||||||
ITx txSel = (ITx) o;
|
TrackEntry trackEntry = selList.size() == 2 && selList.get(1) instanceof TrackEntry
|
||||||
TrackEntry trackEntry = selList.size() == 2 && selList.get(1) instanceof TrackEntry
|
? (TrackEntry) selList.get(1)
|
||||||
? (TrackEntry) selList.get(1)
|
: null;
|
||||||
: null;
|
if (trackEntry == null) {
|
||||||
if (trackEntry == null) {
|
trackEntry = getEntryFor(txSel);
|
||||||
trackEntry = getEntryFor(txSel);
|
if (trackEntry == null && addIfNeeded) {
|
||||||
if (trackEntry == null && addIfNeeded) {
|
trackEntry = new TrackEntry(txSel.getStream(), styleProvider);
|
||||||
trackEntry = new TrackEntry(txSel.getStream(), styleProvider);
|
streams.add(trackEntry);
|
||||||
streams.add(trackEntry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
currentTxSelection = txSel;
|
|
||||||
currentWaveformSelection.clear();
|
|
||||||
currentWaveformSelection.add(trackEntry);
|
|
||||||
selectionChanged = true;
|
|
||||||
} else if (o instanceof TrackEntry) {
|
|
||||||
TrackEntry e = (TrackEntry)o;
|
|
||||||
if(!currentWaveformSelection.contains(e))
|
|
||||||
currentWaveformSelection.add(e);
|
|
||||||
selectionChanged = true;
|
|
||||||
}
|
}
|
||||||
|
currentTxSelection = txSel;
|
||||||
|
currentWaveformSelection.clear();
|
||||||
|
currentWaveformSelection.add(trackEntry);
|
||||||
|
selectionChanged = true;
|
||||||
|
} else if (selList.size() == 1 && selList.get(0) instanceof TrackEntry) {
|
||||||
|
currentWaveformSelection.add((TrackEntry) selList.get(0));
|
||||||
|
if (currentTxSelection != null)
|
||||||
|
currentTxSelection = null;
|
||||||
|
selectionChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -980,7 +930,7 @@ public class WaveformView implements IWaveformView {
|
|||||||
return candidates.get(0);
|
return candidates.get(0);
|
||||||
default:
|
default:
|
||||||
ArrayList<ITxRelation> visibleCandidates = candidates.stream().filter(this::streamsVisible)
|
ArrayList<ITxRelation> visibleCandidates = candidates.stream().filter(this::streamsVisible)
|
||||||
.collect(Collectors.toCollection(ArrayList::new));
|
.collect(Collectors.toCollection(ArrayList::new));
|
||||||
if (visibleCandidates.isEmpty()) {
|
if (visibleCandidates.isEmpty()) {
|
||||||
return new RelSelectionDialog(waveformCanvas.getShell(), candidates, target).open();
|
return new RelSelectionDialog(waveformCanvas.getShell(), candidates, target).open();
|
||||||
} else if (visibleCandidates.size() == 1) {
|
} else if (visibleCandidates.size() == 1) {
|
||||||
@ -1165,6 +1115,16 @@ public class WaveformView implements IWaveformView {
|
|||||||
this.waveformCanvas.setHighliteRelation(relationType);
|
this.waveformCanvas.setHighliteRelation(relationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.minres.scviewer.database.swt.IWaveformPanel#getMaxTime()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public long getMaxTime() {
|
||||||
|
return waveformCanvas.getMaxTime();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
@ -1175,6 +1135,27 @@ public class WaveformView implements IWaveformView {
|
|||||||
this.waveformCanvas.setMaxTime(maxTime);
|
this.waveformCanvas.setMaxTime(maxTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.minres.scviewer.database.swt.IWaveformPanel#setZoomLevel(int)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setZoomLevel(int scale) {
|
||||||
|
waveformCanvas.setZoomLevel(scale);
|
||||||
|
waveformCanvas.reveal(getCursorTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.minres.scviewer.database.swt.IWaveformPanel#getZoomLevel()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int getZoomLevel() {
|
||||||
|
return waveformCanvas.getZoomLevel();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
@ -1193,10 +1174,10 @@ public class WaveformView implements IWaveformView {
|
|||||||
* @see com.minres.scviewer.database.swt.IWaveformPanel#setMarkerTime(long, int)
|
* @see com.minres.scviewer.database.swt.IWaveformPanel#setMarkerTime(long, int)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setMarkerTime(int marker, long time) {
|
public void setMarkerTime(long time, int index) {
|
||||||
if (waveformCanvas.getCursorPainters().size() > marker + 1) {
|
if (waveformCanvas.getCursorPainters().size() > index + 1) {
|
||||||
final Long oldVal = waveformCanvas.getCursorPainters().get(1 + marker).getTime();
|
final Long oldVal = waveformCanvas.getCursorPainters().get(1 + index).getTime();
|
||||||
waveformCanvas.getCursorPainters().get(1 + marker).setTime(time);
|
waveformCanvas.getCursorPainters().get(1 + index).setTime(time);
|
||||||
pcs.firePropertyChange(MARKER_PROPERTY, oldVal, time);
|
pcs.firePropertyChange(MARKER_PROPERTY, oldVal, time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1217,7 +1198,7 @@ public class WaveformView implements IWaveformView {
|
|||||||
* @see com.minres.scviewer.database.swt.IWaveformPanel#getActMarkerTime()
|
* @see com.minres.scviewer.database.swt.IWaveformPanel#getActMarkerTime()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int getSelectedMarker() {
|
public int getSelectedMarkerId() {
|
||||||
return selectedMarker;
|
return selectedMarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1249,7 +1230,7 @@ public class WaveformView implements IWaveformView {
|
|||||||
if (event.y < tracksVerticalHeight) {
|
if (event.y < tracksVerticalHeight) {
|
||||||
event.doit = true;
|
event.doit = true;
|
||||||
LocalSelectionTransfer.getTransfer()
|
LocalSelectionTransfer.getTransfer()
|
||||||
.setSelection(new StructuredSelection(currentWaveformSelection));
|
.setSelection(new StructuredSelection(currentWaveformSelection));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1469,32 +1450,58 @@ public class WaveformView implements IWaveformView {
|
|||||||
return this.pcs.hasListeners(propertyName);
|
return this.pcs.hasListeners(propertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.minres.scviewer.database.swt.IWaveformPanel#getScaledTime(long)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getScaledTime(long time) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
double dTime = time;
|
||||||
|
double scaledTime = dTime / waveformCanvas.getScaleFactorPow10();
|
||||||
|
return sb.append(df.format(scaledTime)).append(waveformCanvas.getUnitStr()).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see com.minres.scviewer.database.swt.IWaveformPanel#getZoomLevels()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String[] getZoomLevels() {
|
||||||
|
String[] res = new String[Constants.UNIT_MULTIPLIER.length * Constants.UNIT_STRING.length];
|
||||||
|
int index = 0;
|
||||||
|
for (String unit : Constants.UNIT_STRING) {
|
||||||
|
for (int factor : Constants.UNIT_MULTIPLIER) {
|
||||||
|
res[index++] = Integer.toString(factor) + unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getBaselineTime() {
|
||||||
|
return -waveformCanvas.getScaleFactorPow10() * waveformCanvas.getOrigin().x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBaselineTime(Long time) {
|
||||||
|
Point origin = waveformCanvas.getOrigin();
|
||||||
|
origin.x = (int) (-time / waveformCanvas.getScaleFactorPow10());
|
||||||
|
waveformCanvas.setOrigin(origin);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void scrollHorizontal(int percent) {
|
public void scrollHorizontal(int percent) {
|
||||||
if (percent < -100)
|
if (percent < -100)
|
||||||
percent = -100;
|
percent = -100;
|
||||||
if (percent > 100)
|
if (percent > 100)
|
||||||
percent = 100;
|
percent = 100;
|
||||||
long minTime = waveformCanvas.getMinVisibleTime();
|
int diff = (waveformCanvas.getWidth() * percent) / 100;
|
||||||
long duration = waveformCanvas.getMaxVisibleTime()-minTime;
|
Point o = waveformCanvas.getOrigin();
|
||||||
long diff = (duration * percent) / 100;
|
waveformCanvas.setOrigin(o.x - diff, o.y);
|
||||||
waveformCanvas.setMinVisibleTime(minTime+diff);
|
waveformCanvas.redraw();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void scrollTo(int pos) {
|
|
||||||
long time = 0;
|
|
||||||
switch(pos) {
|
|
||||||
case IWaveformView.CURSOR_POS:
|
|
||||||
time = getCursorTime();
|
|
||||||
break;
|
|
||||||
case IWaveformView.MARKER_POS:
|
|
||||||
time = getMarkerTime(selectedMarker);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
waveformCanvas.centerAt(time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void asyncUpdate(Widget widget) {
|
public void asyncUpdate(Widget widget) {
|
||||||
@ -1527,12 +1534,4 @@ public class WaveformView implements IWaveformView {
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean waveformsContainsTx() {
|
|
||||||
return streams.stream().filter(e -> e.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IWaveformZoom getWaveformZoom() {
|
|
||||||
return waveformCanvas;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,35 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.internal.slider;
|
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
|
|
||||||
public class ActionTimer implements Runnable {
|
|
||||||
|
|
||||||
public static final int INITIAL_DELAY = 300;
|
|
||||||
public static final int FAST_DELAY = 50;
|
|
||||||
|
|
||||||
private final Display display;
|
|
||||||
private final TimerAction timerAction;
|
|
||||||
|
|
||||||
public interface TimerAction extends Runnable {
|
|
||||||
boolean isEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionTimer( TimerAction timerAction, Display display ) {
|
|
||||||
this.display = display;
|
|
||||||
this.timerAction = timerAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void activate() {
|
|
||||||
if( timerAction.isEnabled() ) {
|
|
||||||
display.timerExec( INITIAL_DELAY, this );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if( timerAction.isEnabled() ) {
|
|
||||||
timerAction.run();
|
|
||||||
display.timerExec( FAST_DELAY, this );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,192 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.internal.slider;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.SWTException;
|
|
||||||
import org.eclipse.swt.events.MouseAdapter;
|
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.events.MouseTrackAdapter;
|
|
||||||
import org.eclipse.swt.events.SelectionListener;
|
|
||||||
import org.eclipse.swt.graphics.GC;
|
|
||||||
import org.eclipse.swt.graphics.Image;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
|
|
||||||
public class ImageButton extends Composite
|
|
||||||
{
|
|
||||||
private Image hoverImage;
|
|
||||||
private Image normalImage;
|
|
||||||
private Image pressedImage;
|
|
||||||
private Image disabledImage;
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
private boolean hover;
|
|
||||||
private boolean pressed;
|
|
||||||
private boolean autoFire;
|
|
||||||
private ActionTimer actionTimer;
|
|
||||||
private ActionTimer.TimerAction timerAction;
|
|
||||||
|
|
||||||
public ImageButton(Composite parent, int style) {
|
|
||||||
super(parent, style);
|
|
||||||
timerAction = new ActionTimer.TimerAction() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
notifyListeners();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return pressed;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
actionTimer = new ActionTimer(timerAction, this.getDisplay() );
|
|
||||||
addListener(SWT.Dispose, event -> {
|
|
||||||
if (hoverImage != null) hoverImage.dispose();
|
|
||||||
if (normalImage != null) normalImage.dispose();
|
|
||||||
if (pressedImage != null) pressedImage.dispose();
|
|
||||||
if (disabledImage != null) disabledImage.dispose();
|
|
||||||
});
|
|
||||||
addListener(SWT.Paint, event -> {
|
|
||||||
paintControl(event);
|
|
||||||
});
|
|
||||||
addMouseTrackListener(new MouseTrackAdapter() {
|
|
||||||
public void mouseEnter(MouseEvent arg0) {
|
|
||||||
if(isEnabled()) {
|
|
||||||
hover=true;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void mouseExit(MouseEvent arg0) {
|
|
||||||
if(isEnabled()) {
|
|
||||||
hover=false;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
addMouseListener(new MouseAdapter() {
|
|
||||||
@Override
|
|
||||||
public void mouseDown(MouseEvent e) {
|
|
||||||
if(isEnabled()) {
|
|
||||||
pressed=true;
|
|
||||||
notifyListeners();
|
|
||||||
if(autoFire) actionTimer.activate();
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseUp(MouseEvent e) {
|
|
||||||
pressed=false;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void paintControl(Event event) {
|
|
||||||
GC gc = event.gc;
|
|
||||||
if (hoverImage != null) {
|
|
||||||
if(pressed)
|
|
||||||
gc.drawImage(pressedImage, 1, 1);
|
|
||||||
else if(hover) {
|
|
||||||
gc.drawImage(hoverImage, 1, 1);
|
|
||||||
} else if(isEnabled()){
|
|
||||||
gc.drawImage(normalImage, 1, 1);
|
|
||||||
} else
|
|
||||||
gc.drawImage(disabledImage, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImage(Image[] imgs) {
|
|
||||||
assert(imgs.length==3);
|
|
||||||
Display d = Display.getDefault();
|
|
||||||
normalImage = new Image(d, imgs[0], SWT.IMAGE_COPY);
|
|
||||||
hoverImage = new Image(d, imgs[1], SWT.IMAGE_COPY);
|
|
||||||
pressedImage = new Image(d, imgs[2], SWT.IMAGE_COPY);
|
|
||||||
disabledImage = new Image(d, imgs[0], SWT.IMAGE_DISABLE);
|
|
||||||
width = imgs[0].getBounds().width;
|
|
||||||
height = imgs[0].getBounds().height;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point computeSize(int wHint, int hHint, boolean changed) {
|
|
||||||
int overallWidth = width;
|
|
||||||
int overallHeight = height;
|
|
||||||
if (wHint != SWT.DEFAULT && wHint < overallWidth)
|
|
||||||
overallWidth = wHint;
|
|
||||||
if (hHint != SWT.DEFAULT && hHint < overallHeight)
|
|
||||||
overallHeight = hHint;
|
|
||||||
return new Point(overallWidth + 2, overallHeight + 2);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Adds the listener to the collection of listeners who will be notified when
|
|
||||||
* the user changes the receiver's value, by sending it one of the messages
|
|
||||||
* defined in the <code>SelectionListener</code> interface.
|
|
||||||
* <p>
|
|
||||||
* <code>widgetSelected</code> is called when the user changes the receiver's
|
|
||||||
* value. <code>widgetDefaultSelected</code> is not called.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param listener the listener which should be notified
|
|
||||||
*
|
|
||||||
* @exception IllegalArgumentException
|
|
||||||
* <ul>
|
|
||||||
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
|
|
||||||
* </ul>
|
|
||||||
* @exception SWTException
|
|
||||||
* <ul>
|
|
||||||
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
|
|
||||||
* disposed</li>
|
|
||||||
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
|
|
||||||
* thread that created the receiver</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @see SelectionListener
|
|
||||||
* @see #removeSelectionListener
|
|
||||||
*/
|
|
||||||
public void addSelectionListener(final SelectionListener listener) {
|
|
||||||
checkWidget();
|
|
||||||
SelectionListenerUtil.addSelectionListener(this, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the listener from the collection of listeners who will be notified
|
|
||||||
* when the user changes the receiver's value.
|
|
||||||
*
|
|
||||||
* @param listener the listener which should no longer be notified
|
|
||||||
*
|
|
||||||
* @exception IllegalArgumentException
|
|
||||||
* <ul>
|
|
||||||
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
|
|
||||||
* </ul>
|
|
||||||
* @exception SWTException
|
|
||||||
* <ul>
|
|
||||||
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
|
|
||||||
* disposed</li>
|
|
||||||
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
|
|
||||||
* thread that created the receiver</li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @see SelectionListener
|
|
||||||
* @see #addSelectionListener
|
|
||||||
*/
|
|
||||||
public void removeSelectionListener(final SelectionListener listener) {
|
|
||||||
checkWidget();
|
|
||||||
SelectionListenerUtil.removeSelectionListener(this, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void notifyListeners() {
|
|
||||||
Event e = new Event();
|
|
||||||
e.widget=this;
|
|
||||||
e.type=SWT.Selection;
|
|
||||||
SelectionListenerUtil.fireSelectionListeners(this,e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAutoFire() {
|
|
||||||
return autoFire;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAutoFire(boolean autoFire) {
|
|
||||||
this.autoFire = autoFire;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,631 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.internal.slider;
|
|
||||||
|
|
||||||
import java.text.Format;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.events.MouseTrackAdapter;
|
|
||||||
import org.eclipse.swt.events.PaintEvent;
|
|
||||||
import org.eclipse.swt.events.SelectionListener;
|
|
||||||
import org.eclipse.swt.graphics.GC;
|
|
||||||
import org.eclipse.swt.graphics.Image;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Canvas;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
import org.eclipse.wb.swt.SWTResourceManager;
|
|
||||||
|
|
||||||
public class RangeSlider extends Canvas {
|
|
||||||
|
|
||||||
private static final int NONE = 0;
|
|
||||||
private static final int UPPER = 1 << 0;
|
|
||||||
private static final int LOWER = 1 << 1;
|
|
||||||
private static final int BOTH = UPPER | LOWER;
|
|
||||||
|
|
||||||
private final int minHeight;
|
|
||||||
private final int markerWidth;
|
|
||||||
private final int thumbWidth = 0;
|
|
||||||
private final Image[] slider, sliderHover, sliderDrag;
|
|
||||||
|
|
||||||
private int minimum;
|
|
||||||
private int maximum;
|
|
||||||
private int lowerValue;
|
|
||||||
private int upperValue;
|
|
||||||
|
|
||||||
private int increment;
|
|
||||||
private int pageIncrement;
|
|
||||||
private int selectedElement;
|
|
||||||
private boolean upperHover, lowerHover;
|
|
||||||
private int previousUpperValue, previousLowerValue;
|
|
||||||
private int startDragUpperValue, startDragLowerValue;
|
|
||||||
private Point startDragPoint;
|
|
||||||
private final boolean isFullSelection=false;
|
|
||||||
private final boolean isHighQuality;
|
|
||||||
private final boolean isOn;
|
|
||||||
private Format toolTipFormatter;
|
|
||||||
private String clientToolTipText;
|
|
||||||
private StringBuffer toolTip;
|
|
||||||
private Point coordUpper;
|
|
||||||
private Point coordLower;
|
|
||||||
|
|
||||||
public RangeSlider(final Composite parent, final int style) {
|
|
||||||
super(parent, SWT.DOUBLE_BUFFERED | ((style & SWT.BORDER) == SWT.BORDER ? SWT.BORDER : SWT.NONE));
|
|
||||||
slider = new Image[] {
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "marker_l.png"),
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "marker_r.png")};
|
|
||||||
sliderHover = new Image[] {
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "marker_l_hover.png"),
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "marker_r_hover.png")};
|
|
||||||
sliderDrag = new Image[] {
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "marker_l_pressed.png"),
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "marker_r_pressed.png")};
|
|
||||||
Rectangle imgSize = slider[0].getBounds();
|
|
||||||
minHeight =imgSize.height+2;
|
|
||||||
markerWidth = imgSize.width;
|
|
||||||
minimum = lowerValue = 0;
|
|
||||||
maximum = upperValue = 100;
|
|
||||||
increment = 1;
|
|
||||||
pageIncrement = 10;
|
|
||||||
isHighQuality = (style & SWT.HIGH) == SWT.HIGH;
|
|
||||||
isOn = (style & SWT.ON) == SWT.ON;
|
|
||||||
selectedElement = NONE;
|
|
||||||
|
|
||||||
addMouseListeners();
|
|
||||||
addListener(SWT.Resize, event -> {
|
|
||||||
});
|
|
||||||
addListener(SWT.KeyDown, event -> {
|
|
||||||
handleKeyDown(event);
|
|
||||||
});
|
|
||||||
addPaintListener(event -> {
|
|
||||||
drawWidget(event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStyle() {
|
|
||||||
return super.getStyle() | //
|
|
||||||
(isOn ? SWT.ON : SWT.NONE) | //
|
|
||||||
(isFullSelection ? SWT.CONTROL : SWT.NONE) | //
|
|
||||||
(isHighQuality ? SWT.HIGH : SWT.NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addMouseListeners() {
|
|
||||||
addListener(SWT.MouseDown, e -> {
|
|
||||||
if (e.button == 1 || e.button == 2) {
|
|
||||||
selectKnobs(e);
|
|
||||||
selectedElement = (lowerHover ? LOWER : NONE) | (upperHover ? UPPER : NONE);
|
|
||||||
if (selectedElement!=NONE) {
|
|
||||||
if((e.stateMask & SWT.CTRL)==0 && e.button != 2)
|
|
||||||
selectedElement=BOTH;
|
|
||||||
startDragLowerValue = previousLowerValue = lowerValue;
|
|
||||||
startDragUpperValue = previousUpperValue = upperValue;
|
|
||||||
startDragPoint = new Point(e.x, e.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addListener(SWT.MouseUp, e -> {
|
|
||||||
if (selectedElement!=NONE) {
|
|
||||||
startDragPoint = null;
|
|
||||||
validateNewValues(e);
|
|
||||||
super.setToolTipText(clientToolTipText);
|
|
||||||
selectedElement=NONE;
|
|
||||||
redraw();
|
|
||||||
} else if (e.button == 1) {
|
|
||||||
if(e.x<coordLower.x) {
|
|
||||||
translateValues(-pageIncrement);
|
|
||||||
validateNewValues(e);
|
|
||||||
redraw();
|
|
||||||
} else if(e.x>coordUpper.x+markerWidth) {
|
|
||||||
translateValues(pageIncrement);
|
|
||||||
validateNewValues(e);
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
addListener(SWT.MouseDoubleClick, event -> {
|
|
||||||
handleMouseDoubleClick(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
addListener(SWT.MouseMove, event -> {
|
|
||||||
handleMouseMove(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
addListener(SWT.MouseWheel, event -> {
|
|
||||||
handleMouseWheel(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
addListener(SWT.MouseHover, event -> {
|
|
||||||
handleMouseHover(event);
|
|
||||||
});
|
|
||||||
|
|
||||||
addMouseTrackListener(new MouseTrackAdapter() {
|
|
||||||
public void mouseExit(MouseEvent event) {
|
|
||||||
lowerHover = upperHover = false;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateNewValues(final Event e) {
|
|
||||||
if (upperValue != previousUpperValue || lowerValue != previousLowerValue) {
|
|
||||||
if (!SelectionListenerUtil.fireSelectionListeners(this,e)) {
|
|
||||||
upperValue = previousUpperValue;
|
|
||||||
lowerValue = previousLowerValue;
|
|
||||||
}
|
|
||||||
previousUpperValue = upperValue;
|
|
||||||
previousLowerValue = lowerValue;
|
|
||||||
increment = Math.max(1, (upperValue-lowerValue)/100);
|
|
||||||
pageIncrement = Math.max(1, (upperValue-lowerValue)/2);
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean busy = false;
|
|
||||||
|
|
||||||
private void handleMouseMove(final Event e) {
|
|
||||||
if (selectedElement==NONE) {
|
|
||||||
final boolean wasUpper = upperHover;
|
|
||||||
final boolean wasLower = lowerHover;
|
|
||||||
selectKnobs(e);
|
|
||||||
if (wasUpper != upperHover || wasLower != lowerHover) {
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
} else { // dragInProgress
|
|
||||||
final int x = e.x;
|
|
||||||
if (selectedElement == BOTH) {
|
|
||||||
final int diff = (int) ((startDragPoint.x - x) / computePixelSizeForSlider()) + minimum;
|
|
||||||
int newUpper = startDragUpperValue - diff;
|
|
||||||
int newLower = startDragLowerValue - diff;
|
|
||||||
if (newUpper > maximum) {
|
|
||||||
newUpper = maximum;
|
|
||||||
newLower = maximum - (startDragUpperValue - startDragLowerValue);
|
|
||||||
} else if (newLower < minimum) {
|
|
||||||
newLower = minimum;
|
|
||||||
newUpper = minimum + startDragUpperValue - startDragLowerValue;
|
|
||||||
}
|
|
||||||
upperValue = newUpper;
|
|
||||||
lowerValue = newLower;
|
|
||||||
handleToolTip(lowerValue, upperValue);
|
|
||||||
} else if (selectedElement == UPPER) {
|
|
||||||
upperValue = (int) Math.round((double)(x - markerWidth) / computePixelSizeForSlider()) + minimum;
|
|
||||||
checkUpperValue();
|
|
||||||
handleToolTip(upperValue);
|
|
||||||
} else if (selectedElement == LOWER){
|
|
||||||
lowerValue = (int) Math.round((double)(x - markerWidth) / computePixelSizeForSlider()) + minimum;
|
|
||||||
checkLowerValue();
|
|
||||||
handleToolTip(lowerValue);
|
|
||||||
}
|
|
||||||
if (isOn && !busy) {
|
|
||||||
validateNewValues(e);
|
|
||||||
busy=true;
|
|
||||||
getDisplay().timerExec(50, ()->{busy=false;});
|
|
||||||
} else {
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isBetweenKnobs(int x, int y) {
|
|
||||||
return x < coordUpper.x && x > coordLower.x && y >= minHeight/3 && y <= minHeight/3 + getClientArea().height - 2*minHeight/3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectKnobs(final Event e) {
|
|
||||||
if (coordLower != null) {
|
|
||||||
final Rectangle imgBounds = slider[0].getBounds();
|
|
||||||
final int x = e.x, y = e.y;
|
|
||||||
lowerHover = x >= coordLower.x && x <= coordLower.x + imgBounds.width && y >= coordLower.y && y <= coordLower.y + imgBounds.height;
|
|
||||||
upperHover = ((e.stateMask & (SWT.CTRL | SWT.SHIFT)) != 0 || !lowerHover) && //
|
|
||||||
x >= coordUpper.x && x <= coordUpper.x + imgBounds.width && //
|
|
||||||
y >= coordUpper.y && y <= coordUpper.y + imgBounds.height;
|
|
||||||
lowerHover &= (e.stateMask & SWT.CTRL) != 0 || !upperHover;
|
|
||||||
if (!lowerHover && !upperHover && isBetweenKnobs(x, y)) {
|
|
||||||
lowerHover = upperHover = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getCursorValue(int x, int y) {
|
|
||||||
int value = -1;
|
|
||||||
final Rectangle clientArea = getClientArea();
|
|
||||||
if (x < clientArea.width - 2*markerWidth && x >= markerWidth && y >= minHeight/3 && y <= clientArea.height - minHeight/3) {
|
|
||||||
value = (int) Math.round((x - 9d) / computePixelSizeForSlider()) + minimum;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMouseDoubleClick(final Event e) {
|
|
||||||
final int value = getCursorValue(e.x, e.y);
|
|
||||||
if (value >= 0) {
|
|
||||||
if (value > upperValue) {
|
|
||||||
translateValues(value-upperValue);
|
|
||||||
} else if (value < lowerValue) {
|
|
||||||
translateValues(value-lowerValue);
|
|
||||||
}
|
|
||||||
validateNewValues(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleToolTip(int... values) {
|
|
||||||
if (toolTipFormatter != null) {
|
|
||||||
try {
|
|
||||||
if (values.length == 1) {
|
|
||||||
toolTip.setLength(0);
|
|
||||||
toolTipFormatter.format(values[0], toolTip, null);
|
|
||||||
super.setToolTipText(toolTip.toString());
|
|
||||||
} else if (values.length == 2) {
|
|
||||||
toolTip.setLength(0);
|
|
||||||
toolTipFormatter.format(values[0], toolTip, null);
|
|
||||||
toolTip.append(" \u2194 "); // LEFT RIGHT ARROW
|
|
||||||
toolTipFormatter.format(values[1], toolTip, null);
|
|
||||||
super.setToolTipText(toolTip.toString());
|
|
||||||
}
|
|
||||||
} catch (final IllegalArgumentException ex) {
|
|
||||||
super.setToolTipText(clientToolTipText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMouseHover(final Event e) {
|
|
||||||
if (selectedElement!=NONE && toolTipFormatter != null) {
|
|
||||||
final int value = getCursorValue(e.x, e.y);
|
|
||||||
if (value >= 0) {
|
|
||||||
try {
|
|
||||||
toolTip.setLength(0);
|
|
||||||
toolTipFormatter.format(value, toolTip, null);
|
|
||||||
super.setToolTipText(toolTip.toString());
|
|
||||||
} catch (final IllegalArgumentException ex) {
|
|
||||||
super.setToolTipText(clientToolTipText);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
super.setToolTipText(clientToolTipText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setToolTipFormatter(Format formatter) {
|
|
||||||
toolTip = formatter != null ? new StringBuffer() : null;
|
|
||||||
toolTipFormatter = formatter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setToolTipText(String string) {
|
|
||||||
super.setToolTipText(clientToolTipText = string);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMouseWheel(final Event e) {
|
|
||||||
previousLowerValue = lowerValue;
|
|
||||||
previousUpperValue = upperValue;
|
|
||||||
final int amount = Math.max(1, ((e.stateMask & SWT.SHIFT) != 0 ? (upperValue-lowerValue)/6 : (upperValue-lowerValue)/15));
|
|
||||||
if ((e.stateMask&SWT.CTRL)==0) {
|
|
||||||
int newLower = lowerValue + e.count * amount;
|
|
||||||
int newUpper = upperValue + e.count * amount;
|
|
||||||
if (newUpper > maximum) {
|
|
||||||
newUpper = maximum;
|
|
||||||
newLower = maximum - (upperValue - lowerValue);
|
|
||||||
} else if (newLower < minimum) {
|
|
||||||
newLower = minimum;
|
|
||||||
newUpper = minimum + upperValue - lowerValue;
|
|
||||||
}
|
|
||||||
upperValue = newUpper;
|
|
||||||
lowerValue = newLower;
|
|
||||||
} else {
|
|
||||||
int newLower = lowerValue + e.count * amount/2;
|
|
||||||
int newUpper = upperValue - e.count * amount/2;
|
|
||||||
int dist = newUpper - newLower;
|
|
||||||
if (newUpper > maximum) {
|
|
||||||
newUpper = maximum;
|
|
||||||
newLower = maximum - dist;
|
|
||||||
} else if (newLower < minimum) {
|
|
||||||
newLower = minimum;
|
|
||||||
newUpper = minimum + dist;
|
|
||||||
}
|
|
||||||
if(newUpper<=newLower) {
|
|
||||||
newLower=lowerValue + (upperValue - lowerValue)/2;
|
|
||||||
newUpper=newLower+1;
|
|
||||||
}
|
|
||||||
upperValue = newUpper;
|
|
||||||
lowerValue = newLower;
|
|
||||||
}
|
|
||||||
validateNewValues(e);
|
|
||||||
e.doit = false; // we are consuming this event
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkLowerValue() {
|
|
||||||
if (lowerValue < minimum) {
|
|
||||||
lowerValue = minimum;
|
|
||||||
} else if (lowerValue > (upperValue-thumbWidth)) {
|
|
||||||
lowerValue = (upperValue-thumbWidth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkUpperValue() {
|
|
||||||
if (upperValue > maximum) {
|
|
||||||
upperValue = maximum;
|
|
||||||
} else if (upperValue < (lowerValue+thumbWidth)) {
|
|
||||||
upperValue = lowerValue+thumbWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private float computePixelSizeForSlider() {
|
|
||||||
return (getClientArea().width - 2.0f*markerWidth) / (maximum - minimum);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawWidget(final PaintEvent e) {
|
|
||||||
final Rectangle rect = getClientArea();
|
|
||||||
if (rect.width == 0 || rect.height == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.gc.setAdvanced(true);
|
|
||||||
e.gc.setAntialias(SWT.ON);
|
|
||||||
drawBackground(e.gc);
|
|
||||||
if (lowerHover || (selectedElement & LOWER) != 0) {
|
|
||||||
coordUpper = drawMarker(e.gc, upperValue, true);
|
|
||||||
coordLower = drawMarker(e.gc, lowerValue, false);
|
|
||||||
} else {
|
|
||||||
coordLower = drawMarker(e.gc, lowerValue, false);
|
|
||||||
coordUpper = drawMarker(e.gc, upperValue, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawBackground(final GC gc) {
|
|
||||||
final Rectangle clientArea = getClientArea();
|
|
||||||
gc.setBackground(getBackground());
|
|
||||||
gc.fillRectangle(clientArea);
|
|
||||||
if (isEnabled()) {
|
|
||||||
gc.setForeground(getForeground());
|
|
||||||
} else {
|
|
||||||
gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_GRAY));
|
|
||||||
}
|
|
||||||
gc.drawRoundRectangle(markerWidth, minHeight/3, clientArea.width - 2*markerWidth, clientArea.height - 2*minHeight/3, 3, 3);
|
|
||||||
|
|
||||||
final float pixelSize = computePixelSizeForSlider();
|
|
||||||
final int startX = (int) (pixelSize * lowerValue);
|
|
||||||
final int endX = (int) (pixelSize * upperValue);
|
|
||||||
if (isEnabled()) {
|
|
||||||
gc.setBackground(getForeground());
|
|
||||||
} else {
|
|
||||||
gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GRAY));
|
|
||||||
}
|
|
||||||
gc.fillRectangle(markerWidth+startX, minHeight/3, endX - startX, clientArea.height - 2*minHeight/3);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point drawMarker(final GC gc, final int value, final boolean upper) {
|
|
||||||
final float pixelSize = computePixelSizeForSlider();
|
|
||||||
int x = (int) (pixelSize * value);
|
|
||||||
final int idx = upper?1:0;
|
|
||||||
Image image;
|
|
||||||
if (upper) {
|
|
||||||
if (upperHover) {
|
|
||||||
image = (selectedElement & UPPER) != 0 ? sliderDrag[idx] : sliderHover[idx];
|
|
||||||
} else {
|
|
||||||
image = slider[idx];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (lowerHover) {
|
|
||||||
image = (selectedElement & LOWER) != 0 ? sliderDrag[idx] : sliderHover[idx];
|
|
||||||
} else {
|
|
||||||
image = slider[idx];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(upper)
|
|
||||||
x+=slider[idx].getBounds().width;
|
|
||||||
if (isEnabled()) {
|
|
||||||
gc.drawImage(image, x, getClientArea().height / 2 - slider[idx].getBounds().height / 2);
|
|
||||||
} else {
|
|
||||||
final Image temp = new Image(getDisplay(), image, SWT.IMAGE_DISABLE);
|
|
||||||
gc.drawImage(temp, x, getClientArea().height / 2 - slider[idx].getBounds().height / 2);
|
|
||||||
temp.dispose();
|
|
||||||
}
|
|
||||||
return new Point(x, getClientArea().height / 2 - slider[idx].getBounds().height / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveCursorPosition(int xDelta, int yDelta) {
|
|
||||||
final Point cursorPosition = getDisplay().getCursorLocation();
|
|
||||||
cursorPosition.x += xDelta;
|
|
||||||
cursorPosition.y += yDelta;
|
|
||||||
getDisplay().setCursorLocation(cursorPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleKeyDown(final Event event) {
|
|
||||||
int accelerator = (event.stateMask & SWT.SHIFT) != 0 ? 10 : (event.stateMask & SWT.CTRL) != 0 ? 2 : 1;
|
|
||||||
if (selectedElement != NONE) {
|
|
||||||
switch (event.keyCode) {
|
|
||||||
case SWT.ESC:
|
|
||||||
startDragPoint = null;
|
|
||||||
upperValue = startDragUpperValue;
|
|
||||||
lowerValue = startDragLowerValue;
|
|
||||||
validateNewValues(event);
|
|
||||||
selectedElement = NONE;
|
|
||||||
if (!isOn) {
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
event.doit = false;
|
|
||||||
break;
|
|
||||||
case SWT.ARROW_UP:
|
|
||||||
accelerator = -accelerator;
|
|
||||||
case SWT.ARROW_LEFT:
|
|
||||||
moveCursorPosition(-accelerator, 0);
|
|
||||||
event.doit = false;
|
|
||||||
break;
|
|
||||||
case SWT.ARROW_DOWN:
|
|
||||||
accelerator = -accelerator;
|
|
||||||
case SWT.ARROW_RIGHT:
|
|
||||||
moveCursorPosition(accelerator, 0);
|
|
||||||
event.doit = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
previousLowerValue = lowerValue;
|
|
||||||
previousUpperValue = upperValue;
|
|
||||||
|
|
||||||
switch (event.keyCode) {
|
|
||||||
case SWT.HOME:
|
|
||||||
if ((event.stateMask & (SWT.SHIFT| SWT.CTRL)) == 0) {
|
|
||||||
upperValue = minimum + upperValue - lowerValue;
|
|
||||||
lowerValue = minimum;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SWT.END:
|
|
||||||
if ((event.stateMask & (SWT.SHIFT| SWT.CTRL)) == 0) {
|
|
||||||
lowerValue = maximum - (upperValue - lowerValue);
|
|
||||||
upperValue = maximum;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SWT.PAGE_UP:
|
|
||||||
translateValues(-accelerator * pageIncrement);
|
|
||||||
break;
|
|
||||||
case SWT.PAGE_DOWN:
|
|
||||||
translateValues( accelerator * pageIncrement);
|
|
||||||
break;
|
|
||||||
case SWT.ARROW_DOWN:
|
|
||||||
case SWT.ARROW_RIGHT:
|
|
||||||
translateValues( accelerator * increment);
|
|
||||||
break;
|
|
||||||
case SWT.ARROW_UP:
|
|
||||||
case SWT.ARROW_LEFT:
|
|
||||||
translateValues(-accelerator * increment);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (previousLowerValue != lowerValue || previousUpperValue != upperValue) {
|
|
||||||
checkLowerValue();
|
|
||||||
checkUpperValue();
|
|
||||||
validateNewValues(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void translateValues(int amount) {
|
|
||||||
int newLower = lowerValue + amount;
|
|
||||||
int newUpper = upperValue + amount;
|
|
||||||
if (newUpper > maximum) {
|
|
||||||
newUpper = maximum;
|
|
||||||
newLower = maximum - (upperValue - lowerValue);
|
|
||||||
} else if (newLower < minimum) {
|
|
||||||
newLower = minimum;
|
|
||||||
newUpper = minimum + upperValue - lowerValue;
|
|
||||||
}
|
|
||||||
upperValue = newUpper;
|
|
||||||
lowerValue = newLower;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSelectionListener(final SelectionListener listener) {
|
|
||||||
checkWidget();
|
|
||||||
SelectionListenerUtil.addSelectionListener(this, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeSelectionListener(final SelectionListener listener) {
|
|
||||||
checkWidget();
|
|
||||||
SelectionListenerUtil.removeSelectionListener(this, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point computeSize(final int wHint, final int hHint, final boolean changed) {
|
|
||||||
checkWidget();
|
|
||||||
final int width = Math.max(2*markerWidth+100, wHint);
|
|
||||||
final int height = Math.max(minHeight, hHint);
|
|
||||||
return new Point(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getSelection() {
|
|
||||||
checkWidget();
|
|
||||||
return new int[] {lowerValue, upperValue};
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIncrement() {
|
|
||||||
checkWidget();
|
|
||||||
return increment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaximum() {
|
|
||||||
checkWidget();
|
|
||||||
return maximum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinimum() {
|
|
||||||
checkWidget();
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPageIncrement() {
|
|
||||||
checkWidget();
|
|
||||||
return pageIncrement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaximum(final int value) {
|
|
||||||
setLimits(minimum, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinimum(final int value) {
|
|
||||||
setLimits(value, maximum);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLimits(final int min, final int max) {
|
|
||||||
checkWidget();
|
|
||||||
if (min >= 0 && min < max && (min != minimum || max != maximum)) {
|
|
||||||
minimum = min;
|
|
||||||
maximum = max;
|
|
||||||
if (lowerValue < minimum) {
|
|
||||||
lowerValue = minimum;
|
|
||||||
} else if (lowerValue > maximum) {
|
|
||||||
lowerValue = maximum;
|
|
||||||
}
|
|
||||||
if (upperValue < minimum) {
|
|
||||||
upperValue = minimum;
|
|
||||||
} else if (upperValue > maximum) {
|
|
||||||
upperValue = maximum;
|
|
||||||
}
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUpperValue() {
|
|
||||||
checkWidget();
|
|
||||||
return upperValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUpperValue(final int value) {
|
|
||||||
setValues(lowerValue, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLowerValue() {
|
|
||||||
checkWidget();
|
|
||||||
return lowerValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLowerValue(final int value) {
|
|
||||||
setValues(value, upperValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValues(final int[] values) {
|
|
||||||
if (values.length == 2) {
|
|
||||||
setValues(values[0], values[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValues(final int lowerValue, final int upperValue) {
|
|
||||||
setValues(lowerValue, upperValue, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setValues(final int lowerValue, final int upperValue, boolean update) {
|
|
||||||
checkWidget();
|
|
||||||
if (lowerValue <= upperValue && lowerValue >= minimum && upperValue <= maximum && (this.lowerValue != lowerValue || this.upperValue != upperValue)) {
|
|
||||||
this.lowerValue = lowerValue;
|
|
||||||
this.upperValue = upperValue;
|
|
||||||
if(update) {
|
|
||||||
Event e = new Event();
|
|
||||||
e.type=SWT.Selection;
|
|
||||||
e.doit=true;
|
|
||||||
validateNewValues(e);
|
|
||||||
} else {
|
|
||||||
increment = Math.max(1, (upperValue-lowerValue)/100);
|
|
||||||
pageIncrement = Math.max(1, (upperValue-lowerValue)/2);
|
|
||||||
}
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.internal.slider;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public class ReflectionUtils {
|
|
||||||
/**
|
|
||||||
* Call a method using introspection (so ones can call a private or protected method)
|
|
||||||
* @param object object on which the method will be called
|
|
||||||
* @param methodName method name
|
|
||||||
* @param args arguments of this method (can be null)
|
|
||||||
* @return the value returned by this method (if this method returns a value)
|
|
||||||
*/
|
|
||||||
public static Object callMethod(final Object object, final String methodName, final Object... args) {
|
|
||||||
if (object == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final Class<?>[] array = new Class<?>[args == null ? 0 : args.length];
|
|
||||||
int index = 0;
|
|
||||||
if (args != null) {
|
|
||||||
for (final Object o : args) {
|
|
||||||
array[index++] = o == null ? Object.class : o.getClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return callMethodWithClassType(object, methodName, array, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object callMethodWithClassType(final Object object, final String methodName, final Class<?>[] array, final Object... args) {
|
|
||||||
Class<?> currentClass = object.getClass();
|
|
||||||
Method method = null;
|
|
||||||
while (currentClass != null) {
|
|
||||||
try {
|
|
||||||
method = currentClass.getDeclaredMethod(methodName, array);
|
|
||||||
break;
|
|
||||||
} catch (final NoSuchMethodException nsme) {
|
|
||||||
currentClass = currentClass.getSuperclass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
method.setAccessible(true);
|
|
||||||
return method.invoke(object, args);
|
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.internal.slider;
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.SelectionListener;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
import org.eclipse.swt.widgets.Listener;
|
|
||||||
import org.eclipse.swt.widgets.TypedListener;
|
|
||||||
|
|
||||||
public class SelectionListenerUtil {
|
|
||||||
/**
|
|
||||||
* Add a <code>SelectionListener</code> to a given Control
|
|
||||||
*
|
|
||||||
* @param control control on which the selection listener is added
|
|
||||||
* @param listener listener to add
|
|
||||||
*/
|
|
||||||
public static void addSelectionListener(final Control control, final SelectionListener listener) {
|
|
||||||
if (listener == null) {
|
|
||||||
SWT.error(SWT.ERROR_NULL_ARGUMENT);
|
|
||||||
}
|
|
||||||
TypedListener typedListener = new TypedListener(listener);
|
|
||||||
control.addListener(SWT.Selection, typedListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a <code>SelectionListener</code> of a given Control
|
|
||||||
*
|
|
||||||
* @param control control on which the selection listener is removed
|
|
||||||
* @param listener listener to remove
|
|
||||||
*/
|
|
||||||
public static void removeSelectionListener(final Control control, final SelectionListener listener) {
|
|
||||||
if (listener == null) {
|
|
||||||
SWT.error(SWT.ERROR_NULL_ARGUMENT);
|
|
||||||
}
|
|
||||||
final Listener[] listeners = control.getListeners(SWT.Selection);
|
|
||||||
for (Listener l : listeners) {
|
|
||||||
if (l instanceof TypedListener) {
|
|
||||||
TypedListener typedListener = (TypedListener) l;
|
|
||||||
if (typedListener.getEventListener() == listener) {
|
|
||||||
ReflectionUtils.callMethod(control, "removeListener", SWT.Selection, ((TypedListener) l).getEventListener());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fire the selection listeners of a given control
|
|
||||||
*
|
|
||||||
* @param control the control that fires the event
|
|
||||||
* @param sourceEvent mouse event
|
|
||||||
* @return true if the selection could be changed, false otherwise
|
|
||||||
*/
|
|
||||||
public static boolean fireSelectionListeners(final Control control, final Event sourceEvent) {
|
|
||||||
for (final Listener listener : control.getListeners(SWT.Selection)) {
|
|
||||||
final Event event = new Event();
|
|
||||||
|
|
||||||
event.button = sourceEvent==null?1:sourceEvent.button;
|
|
||||||
event.display = control.getDisplay();
|
|
||||||
event.item = null;
|
|
||||||
event.widget = control;
|
|
||||||
event.data = sourceEvent == null ? null : sourceEvent.data;
|
|
||||||
event.time = sourceEvent == null ? 0 : sourceEvent.time;
|
|
||||||
event.x = sourceEvent == null ? 0 : sourceEvent.x;
|
|
||||||
event.y = sourceEvent == null ? 0 : sourceEvent.y;
|
|
||||||
event.type = SWT.Selection;
|
|
||||||
|
|
||||||
listener.handleEvent(event);
|
|
||||||
if (!event.doit) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.internal.slider;
|
|
||||||
|
|
||||||
import java.text.Format;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.SelectionAdapter;
|
|
||||||
import org.eclipse.swt.events.SelectionEvent;
|
|
||||||
import org.eclipse.swt.events.SelectionListener;
|
|
||||||
import org.eclipse.swt.graphics.Image;
|
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.wb.swt.SWTResourceManager;
|
|
||||||
|
|
||||||
public class ZoomBar extends Composite {
|
|
||||||
|
|
||||||
static public interface IProvider {
|
|
||||||
ZoomBar getScrollBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
final RangeSlider timeSlider;
|
|
||||||
final ImageButton leftButton;
|
|
||||||
final ImageButton rightButton;
|
|
||||||
/**
|
|
||||||
* Create the composite.
|
|
||||||
* @param parent
|
|
||||||
* @param style
|
|
||||||
*/
|
|
||||||
public ZoomBar(Composite parent, int style) {
|
|
||||||
super(parent, SWT.NO_FOCUS);
|
|
||||||
GridLayout gridLayout = new GridLayout(3, false);
|
|
||||||
gridLayout.horizontalSpacing = 0;
|
|
||||||
gridLayout.verticalSpacing = 0;
|
|
||||||
gridLayout.marginWidth = 0;
|
|
||||||
gridLayout.marginHeight = 0;
|
|
||||||
setLayout(gridLayout);
|
|
||||||
|
|
||||||
leftButton = new ImageButton(this, SWT.NONE);
|
|
||||||
GridData gd_leftButton = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
|
|
||||||
gd_leftButton.widthHint=14;
|
|
||||||
gd_leftButton.heightHint=18;
|
|
||||||
leftButton.setLayoutData(gd_leftButton);
|
|
||||||
leftButton.setImage(new Image[] {
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "arrow_left.png"),
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "arrow_left_hover.png"),
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "arrow_left_pressed.png")});
|
|
||||||
leftButton.setAutoFire(true);
|
|
||||||
|
|
||||||
timeSlider = new RangeSlider(this, SWT.ON|SWT.HIGH|SWT.SMOOTH|SWT.CONTROL);
|
|
||||||
timeSlider.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
|
|
||||||
|
|
||||||
rightButton = new ImageButton(this, SWT.NONE);
|
|
||||||
GridData gd_rightButton = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
|
|
||||||
gd_rightButton.widthHint=18;
|
|
||||||
gd_rightButton.heightHint=18;
|
|
||||||
rightButton.setLayoutData(gd_rightButton);
|
|
||||||
rightButton.setImage(new Image[] {
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "arrow_right.png"),
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "arrow_right_hover.png"),
|
|
||||||
SWTResourceManager.getImage(this.getClass(), "arrow_right_pressed.png")});
|
|
||||||
rightButton.setAutoFire(true);
|
|
||||||
|
|
||||||
leftButton.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
int[] value = timeSlider.getSelection();
|
|
||||||
int incr=timeSlider.getIncrement();
|
|
||||||
int lower = Math.max(timeSlider.getMinimum(), value[0]-incr);
|
|
||||||
timeSlider.setValues(lower, lower + (value[1]-value[0]), true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
rightButton.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
int[] value = timeSlider.getSelection();
|
|
||||||
int incr=timeSlider.getIncrement();
|
|
||||||
int upper = Math.min(timeSlider.getMaximum(), value[1]+incr);
|
|
||||||
timeSlider.setValues(upper - (value[1]-value[0]), upper, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void setEnabled (boolean enabled) {
|
|
||||||
timeSlider.setEnabled(enabled);
|
|
||||||
leftButton.setEnabled(enabled);
|
|
||||||
rightButton.setEnabled(enabled);
|
|
||||||
super.setEnabled(enabled);
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
public void setButtonsEnabled (boolean enabled) {
|
|
||||||
leftButton.setEnabled(enabled);
|
|
||||||
rightButton.setEnabled(enabled);
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
public void setToolTipFormatter(Format formatter){
|
|
||||||
timeSlider.setToolTipFormatter(formatter);
|
|
||||||
}
|
|
||||||
public void setToolTipText(String string) {
|
|
||||||
timeSlider.setToolTipText(string);
|
|
||||||
}
|
|
||||||
public void setSelection(int sel) {
|
|
||||||
timeSlider.setLowerValue(sel);
|
|
||||||
}
|
|
||||||
public void setSelection(int[] sel) {
|
|
||||||
assert(sel.length==2);
|
|
||||||
timeSlider.setValues(sel[0], sel[1]);
|
|
||||||
}
|
|
||||||
public int[] getSelection() {
|
|
||||||
return timeSlider.getSelection();
|
|
||||||
}
|
|
||||||
public void addSelectionListener(SelectionListener selectionListener) {
|
|
||||||
timeSlider.addSelectionListener(selectionListener);
|
|
||||||
}
|
|
||||||
public void setMinimum(int value) {
|
|
||||||
timeSlider.setMinimum(value);
|
|
||||||
}
|
|
||||||
public void setMaximum(int value) {
|
|
||||||
timeSlider.setMaximum(value);
|
|
||||||
}
|
|
||||||
public int getMaximum() {
|
|
||||||
return timeSlider.getMaximum();
|
|
||||||
}
|
|
||||||
public int getMinimum() {
|
|
||||||
return timeSlider.getMinimum();
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 305 B |
Before Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 350 B |
Before Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 329 B |
Before Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 349 B |
@ -1,18 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
|
|
||||||
public class ActionScheduler {
|
|
||||||
|
|
||||||
private final Display display;
|
|
||||||
private final Runnable action;
|
|
||||||
|
|
||||||
public ActionScheduler( Display display, Runnable action ) {
|
|
||||||
this.display = display;
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void schedule( int delay ) {
|
|
||||||
display.timerExec( delay, action );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
|
|
||||||
public class ButtonClick {
|
|
||||||
|
|
||||||
public static final int LEFT_BUTTON = 1;
|
|
||||||
|
|
||||||
private boolean armed;
|
|
||||||
|
|
||||||
public boolean isArmed() {
|
|
||||||
return armed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void arm( MouseEvent event ) {
|
|
||||||
if( event.button == LEFT_BUTTON ) {
|
|
||||||
armed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disarm() {
|
|
||||||
armed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void trigger( MouseEvent event, Runnable action ) {
|
|
||||||
try {
|
|
||||||
doTrigger( event, action );
|
|
||||||
} finally {
|
|
||||||
disarm();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doTrigger( MouseEvent event, Runnable action ) {
|
|
||||||
if( armed && inRange( event ) ) {
|
|
||||||
action.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean inRange( MouseEvent event ) {
|
|
||||||
Point size = ( ( Control )event.widget ).getSize();
|
|
||||||
return event.x >= 0 && event.x <= size.x && event.y >= 0 && event.y <= size.y;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.ControlAdapter;
|
|
||||||
import org.eclipse.swt.events.ControlEvent;
|
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.events.MouseListener;
|
|
||||||
import org.eclipse.swt.events.MouseTrackListener;
|
|
||||||
import org.eclipse.swt.graphics.Color;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Label;
|
|
||||||
|
|
||||||
|
|
||||||
class ClickControl extends ControlAdapter implements ViewComponent, MouseDownActionTimer.TimerAction, MouseListener, MouseTrackListener {
|
|
||||||
|
|
||||||
private final MouseDownActionTimer mouseDownActionTimer;
|
|
||||||
private final ClickAction clickAction;
|
|
||||||
private final ButtonClick buttonClick;
|
|
||||||
private final Label control;
|
|
||||||
private final ImageUpdate imageUpdate;
|
|
||||||
|
|
||||||
public interface ClickAction extends Runnable {
|
|
||||||
void setCoordinates( int x, int y );
|
|
||||||
}
|
|
||||||
|
|
||||||
ClickControl( Composite parent, ClickAction clickAction, int maxExtension ) {
|
|
||||||
this.control = new Label( parent, SWT.NONE );
|
|
||||||
this.imageUpdate = new ImageUpdate( control, maxExtension );
|
|
||||||
this.buttonClick = new ButtonClick();
|
|
||||||
this.mouseDownActionTimer = new MouseDownActionTimer( this, buttonClick, control.getDisplay() );
|
|
||||||
this.clickAction = clickAction;
|
|
||||||
this.control.addMouseTrackListener( this );
|
|
||||||
this.control.addMouseListener( this );
|
|
||||||
this.control.addControlListener( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void controlResized( ControlEvent event ) {
|
|
||||||
imageUpdate.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Label getControl() {
|
|
||||||
return control;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDown( MouseEvent event ) {
|
|
||||||
buttonClick.arm( event );
|
|
||||||
clickAction.setCoordinates( event.x, event.y );
|
|
||||||
mouseDownActionTimer.activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseUp( MouseEvent event ) {
|
|
||||||
buttonClick.trigger( event, clickAction );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
clickAction.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseExit( MouseEvent event ) {
|
|
||||||
buttonClick.disarm();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setForeground( Color color ) {
|
|
||||||
imageUpdate.setForeground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
Color getForeground() {
|
|
||||||
return imageUpdate.getForeground();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBackground( Color color ) {
|
|
||||||
imageUpdate.setBackground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
Color getBackground() {
|
|
||||||
return imageUpdate.getBackground();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseEnter( MouseEvent event ) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseHover( MouseEvent event ) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDoubleClick( MouseEvent event ) {}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import static java.lang.Math.max;
|
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.RoundingMode;
|
|
||||||
|
|
||||||
class ComponentDistribution {
|
|
||||||
|
|
||||||
private static final int MIN_DRAG_LENGTH = 17;
|
|
||||||
|
|
||||||
final int upFastLength;
|
|
||||||
final int dragStart;
|
|
||||||
final int dragLength;
|
|
||||||
final int downFastStart;
|
|
||||||
final int downFastLength;
|
|
||||||
final int downStart;
|
|
||||||
final int buttonLen;
|
|
||||||
|
|
||||||
ComponentDistribution( int buttonLen, int len, int range, int pos, int thumb ) {
|
|
||||||
int slideLen = slideLen( buttonLen, len );
|
|
||||||
int relDragLen = relDragLen( slideLen, range, thumb );
|
|
||||||
int minDragLength = max( MIN_DRAG_LENGTH, buttonLen );
|
|
||||||
int interval = interval( range, relDragLen, minDragLength );
|
|
||||||
this.dragLength = dragLen( minDragLength, relDragLen );
|
|
||||||
this.upFastLength = upFastLen( minDragLength, interval, pos, slideLen, relDragLen, dragLength );
|
|
||||||
this.downStart = downStart( buttonLen, len );
|
|
||||||
this.downFastStart = downFastStart( buttonLen, upFastLength, dragLength );
|
|
||||||
this.dragStart = dragStart( buttonLen, upFastLength );
|
|
||||||
this.downFastLength = downFastLen( minDragLength, interval, pos, slideLen, relDragLen, dragLength, upFastLength );
|
|
||||||
this.buttonLen = buttonLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int slideLen( int buttonLen, int len ) {
|
|
||||||
return len - buttonLen * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int relDragLen( int slideLen, int range, int thumb ) {
|
|
||||||
return divide( slideLen * thumb, range );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int interval( int range, int relDragLen, int minDragLength ) {
|
|
||||||
int result = range;
|
|
||||||
if( useMinDragLen( minDragLength, relDragLen ) ) {
|
|
||||||
result += minDragLength - relDragLen / 2;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int dragLen( int buttonLen, int relDragLen ) {
|
|
||||||
return max( relDragLen, buttonLen );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int upFastLen( int buttonLen, int range, int pos, int slideLen, int relDragLen, int dragLen ) {
|
|
||||||
int result = slideLen * pos / range;
|
|
||||||
if( useMinDragLen( buttonLen, relDragLen ) ) {
|
|
||||||
result -= divide( ( dragLen - relDragLen ) * pos, range );
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int downStart( int buttonLen, int len ) {
|
|
||||||
return len - buttonLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int downFastStart( int buttonLen, int upFastLength, int dragLength ) {
|
|
||||||
return buttonLen + upFastLength + dragLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int dragStart( int buttonLen, int upFastLen ) {
|
|
||||||
return buttonLen + upFastLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int downFastLen(
|
|
||||||
int buttonLen, int range, int pos, int slideLen, int relDragLen, int dragLen, int upFastLen )
|
|
||||||
{
|
|
||||||
int result = divide( slideLen * ( range - pos ), range ) - dragLen;
|
|
||||||
if( useMinDragLen( buttonLen, relDragLen ) ) {
|
|
||||||
result += divide( ( dragLen - relDragLen ) * pos, range );
|
|
||||||
}
|
|
||||||
return adjustDownFastLen( result, slideLen, dragLen, upFastLen );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean useMinDragLen( int buttonLen, int relDragLen ) {
|
|
||||||
return relDragLen < buttonLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int divide( int dividend, int divisor ) {
|
|
||||||
BigDecimal bigDividend = new BigDecimal( dividend );
|
|
||||||
BigDecimal bigDivisor = new BigDecimal( divisor );
|
|
||||||
return bigDividend .divide( bigDivisor, 0, RoundingMode.HALF_EVEN ) .intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int adjustDownFastLen( int tentative, int slideLen, int dragLen, int upFastLen ) {
|
|
||||||
// TODO [fappel]: Without this there is a flickering of the downFast label of one pixel.
|
|
||||||
// Check whether this can be resolved by better rounding or whatsoever.
|
|
||||||
int result = tentative;
|
|
||||||
if( slideLen < upFastLen + dragLen + result ) {
|
|
||||||
result--;
|
|
||||||
} else if( slideLen > upFastLen + dragLen + result ) {
|
|
||||||
result++;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.ui.swt.sb.ClickControl.ClickAction;
|
|
||||||
|
|
||||||
class Decrementer implements ClickAction {
|
|
||||||
|
|
||||||
private final FlatScrollBar scrollBar;
|
|
||||||
|
|
||||||
Decrementer( FlatScrollBar scrollBar ) {
|
|
||||||
this.scrollBar = scrollBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
int selection = scrollBar.getSelection() - scrollBar.getIncrement();
|
|
||||||
scrollBar.setSelectionInternal( selection, SWT.ARROW_UP );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCoordinates( int x, int y ) {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,203 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import static com.minres.scviewer.database.ui.swt.sb.FlatScrollBar.BAR_BREADTH;
|
|
||||||
import static java.lang.Math.max;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
|
|
||||||
enum Direction {
|
|
||||||
|
|
||||||
HORIZONTAL( SWT.HORIZONTAL ) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void layout( FlatScrollBar scrollBar, int buttonLength ) {
|
|
||||||
ComponentDistribution distribution = calculateComponentDistribution( scrollBar, buttonLength );
|
|
||||||
Rectangle[] componentBounds = calculateComponentBounds( distribution, scrollBar );
|
|
||||||
applyComponentBounds( scrollBar, componentBounds );
|
|
||||||
}
|
|
||||||
|
|
||||||
private ComponentDistribution calculateComponentDistribution( FlatScrollBar scrollBar, int buttonLength ) {
|
|
||||||
return calculateComponentDistribution( scrollBar, buttonLength, getControlBounds( scrollBar ).width );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle[] calculateComponentBounds( ComponentDistribution distribution, FlatScrollBar scrollBar ) {
|
|
||||||
int width = getControlBounds( scrollBar ).width;
|
|
||||||
int height = getControlBounds( scrollBar ).height - FlatScrollBar.BAR_BREADTH + 1;
|
|
||||||
int balance = getRoundingBalance( distribution, scrollBar );
|
|
||||||
return new Rectangle[] {
|
|
||||||
calcButtons( distribution, width, $( 0, CLEARANCE, distribution.buttonLen, height ) ),
|
|
||||||
$( distribution.buttonLen, CLEARANCE, distribution.upFastLength, height ),
|
|
||||||
calcDrag( distribution, $( distribution.dragStart, CLEARANCE, distribution.dragLength + balance, height ) ),
|
|
||||||
$( distribution.downFastStart, CLEARANCE, distribution.downFastLength - balance, height ),
|
|
||||||
calcButtons( distribution, width, $( distribution.downStart, CLEARANCE, distribution.buttonLen, height ) )
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle calcButtons( ComponentDistribution distribution, int length, Rectangle bounds ) {
|
|
||||||
Rectangle result = bounds;
|
|
||||||
if( length <= distribution.buttonLen* 2 ) {
|
|
||||||
int downStart = calcDownStartForSmallLength( bounds.x, length );
|
|
||||||
result = $( downStart, CLEARANCE, length / 2, bounds.height );
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setDefaultSize( Control control ) {
|
|
||||||
Point size = control.getSize();
|
|
||||||
control.setSize( size.x, FlatScrollBar.BAR_BREADTH );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Point computeSize( Composite composite, int wHint, int hHint, boolean changed ) {
|
|
||||||
int x = wHint == SWT.DEFAULT ? composite.getParent().getClientArea().width : wHint;
|
|
||||||
return new Point( x, FlatScrollBar.BAR_BREADTH );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void expand( Control control, int maxExpansion ) {
|
|
||||||
Rectangle bounds = control.getBounds();
|
|
||||||
int expand = expand( bounds.height, maxExpansion );
|
|
||||||
control.setBounds( bounds.x, bounds.y - expand, bounds.width, bounds.height + expand );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
VERTICAL( SWT.VERTICAL ) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void layout( FlatScrollBar scrollBar, int buttonLength ) {
|
|
||||||
ComponentDistribution calculation = calculateComponentDistribution( scrollBar, buttonLength );
|
|
||||||
applyComponentBounds( scrollBar, calculateComponentBounds( calculation, scrollBar ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private ComponentDistribution calculateComponentDistribution( FlatScrollBar scrollBar, int buttonLength ) {
|
|
||||||
return calculateComponentDistribution( scrollBar, buttonLength, getControlBounds( scrollBar ).height );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle[] calculateComponentBounds( ComponentDistribution distribution, FlatScrollBar scrollBar ) {
|
|
||||||
int width = getControlBounds( scrollBar ).width - FlatScrollBar.BAR_BREADTH + 1;
|
|
||||||
int height = getControlBounds( scrollBar ).height;
|
|
||||||
int balance = getRoundingBalance( distribution, scrollBar );
|
|
||||||
return new Rectangle[] {
|
|
||||||
calculateButtons( distribution, height, $( CLEARANCE, 0, width, distribution.buttonLen ) ),
|
|
||||||
$( CLEARANCE, distribution.buttonLen, width, distribution.upFastLength ),
|
|
||||||
calcDrag( distribution, $( CLEARANCE, distribution.dragStart, width, distribution.dragLength + balance ) ),
|
|
||||||
$( CLEARANCE, distribution.downFastStart, width, distribution.downFastLength - balance ),
|
|
||||||
calculateButtons( distribution, height, $( CLEARANCE, distribution.downStart, width, distribution.buttonLen ) )
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle calculateButtons( ComponentDistribution distribution, int length, Rectangle bounds ) {
|
|
||||||
Rectangle result = bounds;
|
|
||||||
if( length <= distribution.buttonLen * 2 ) {
|
|
||||||
int downStart = calcDownStartForSmallLength( bounds.y, length );
|
|
||||||
result = $( CLEARANCE, downStart, bounds.width, length / 2 );
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setDefaultSize( Control control ) {
|
|
||||||
Point size = control.getSize();
|
|
||||||
control.setSize( FlatScrollBar.BAR_BREADTH, size.y );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Point computeSize( Composite composite, int wHint, int hHint, boolean changed ) {
|
|
||||||
int y = hHint == SWT.DEFAULT ? composite.getParent().getClientArea().height : hHint;
|
|
||||||
return new Point( FlatScrollBar.BAR_BREADTH, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void expand( Control control, int maxExpansion ) {
|
|
||||||
Rectangle bounds = control.getBounds();
|
|
||||||
int expand = expand( bounds.width, maxExpansion );
|
|
||||||
control.setBounds( bounds.x - expand, bounds.y, bounds.width + expand, bounds.height );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static final Rectangle EMPTY_RECTANGLE = $( 0, 0, 0, 0 );
|
|
||||||
static final int CLEARANCE = BAR_BREADTH - 2;
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
protected abstract void layout( FlatScrollBar scrollBar, int buttonLength );
|
|
||||||
protected abstract void setDefaultSize( Control control );
|
|
||||||
protected abstract Point computeSize( Composite comp, int wHint, int hHint, boolean changed );
|
|
||||||
protected abstract void expand( Control control, int maxExpansion );
|
|
||||||
|
|
||||||
Direction( int value ) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int value() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ComponentDistribution calculateComponentDistribution(
|
|
||||||
FlatScrollBar scrollBar , int buttonLength , int length )
|
|
||||||
{
|
|
||||||
int range = scrollBar.getMaximum() - scrollBar.getMinimum();
|
|
||||||
int position = scrollBar.getSelection() - scrollBar.getMinimum();
|
|
||||||
int thumb = scrollBar.getThumb();
|
|
||||||
return new ComponentDistribution( buttonLength, length, range, position, thumb );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Rectangle getControlBounds( FlatScrollBar scrollBar ) {
|
|
||||||
return scrollBar.getClientArea();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void applyComponentBounds( FlatScrollBar scrollBar, Rectangle[] bounds ) {
|
|
||||||
scrollBar.up.getControl().setBounds( bounds[ 0 ] );
|
|
||||||
scrollBar.upFast.getControl().setBounds( bounds[ 1 ] );
|
|
||||||
scrollBar.drag.getControl().setBounds( bounds[ 2 ] );
|
|
||||||
scrollBar.downFast.getControl().setBounds( bounds[ 3 ] );
|
|
||||||
scrollBar.down.getControl().setBounds( bounds[ 4 ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO [fappel]: There is a 1 pixel rounding problem at the seam of drag/downFast with down.
|
|
||||||
// Seems to work but I would prefer a better solution if possible
|
|
||||||
private static int getRoundingBalance( ComponentDistribution calculation, FlatScrollBar scrollBar ) {
|
|
||||||
int result = 0;
|
|
||||||
int maximumSelection = scrollBar.getMaximum() - scrollBar.getThumb();
|
|
||||||
if( scrollBar.getSelection() == maximumSelection && 0 != calculation.downFastLength ) {
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int expand( int toExpand, int maxExpansion ) {
|
|
||||||
return max( 0, FlatScrollBar.BAR_BREADTH + maxExpansion - max( FlatScrollBar.BAR_BREADTH, toExpand ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Rectangle calcDrag( ComponentDistribution distribution, Rectangle bounds ) {
|
|
||||||
Rectangle result = bounds;
|
|
||||||
if( isUndercutOfDragVisibility( distribution ) ) {
|
|
||||||
result = EMPTY_RECTANGLE;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isUndercutOfDragVisibility( ComponentDistribution distribution ) {
|
|
||||||
return distribution.dragLength + distribution.buttonLen >= distribution.downStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int calcDownStartForSmallLength( int position, int length ) {
|
|
||||||
int result = position;
|
|
||||||
if( isDownStartPosition( position ) ) {
|
|
||||||
result = length / 2;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
private static boolean isDownStartPosition( int position ) {
|
|
||||||
return position > 0 || position < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Rectangle $( int x, int y, int width, int height ) {
|
|
||||||
return new Rectangle( x, y , width , height );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.ControlAdapter;
|
|
||||||
import org.eclipse.swt.events.ControlEvent;
|
|
||||||
import org.eclipse.swt.events.DragDetectEvent;
|
|
||||||
import org.eclipse.swt.events.DragDetectListener;
|
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.events.MouseListener;
|
|
||||||
import org.eclipse.swt.events.MouseMoveListener;
|
|
||||||
import org.eclipse.swt.graphics.Color;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Label;
|
|
||||||
|
|
||||||
|
|
||||||
class DragControl
|
|
||||||
extends ControlAdapter
|
|
||||||
implements ViewComponent, DragDetectListener, MouseListener, MouseMoveListener
|
|
||||||
{
|
|
||||||
|
|
||||||
private final DragDetector dragDetector;
|
|
||||||
private final ImageUpdate imageUpdate;
|
|
||||||
private final DragAction dragAction;
|
|
||||||
private final Label control;
|
|
||||||
|
|
||||||
private Point startingPosition;
|
|
||||||
|
|
||||||
public interface DragAction {
|
|
||||||
void start();
|
|
||||||
void run( int startX, int startY, int currentX, int currentY );
|
|
||||||
void end();
|
|
||||||
}
|
|
||||||
|
|
||||||
DragControl( Composite parent, DragAction dragAction, int maxExpansion ) {
|
|
||||||
this.control = new Label( parent, SWT.NONE );
|
|
||||||
this.imageUpdate = new ImageUpdate( control, maxExpansion );
|
|
||||||
this.dragDetector = new DragDetector( control, 0 );
|
|
||||||
this.dragAction = dragAction;
|
|
||||||
initializeControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Label getControl() {
|
|
||||||
return control;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dragDetected( DragDetectEvent event ) {
|
|
||||||
if( startingPosition != null ) {
|
|
||||||
dragAction.run( startingPosition.x, startingPosition.y, event.x, event.y );
|
|
||||||
}
|
|
||||||
dragDetector.dragHandled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDown( MouseEvent event ) {
|
|
||||||
startingPosition = new Point( event.x, event.y );
|
|
||||||
dragAction.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseUp( MouseEvent event ) {
|
|
||||||
if( startingPosition != null ) {
|
|
||||||
dragAction.end();
|
|
||||||
}
|
|
||||||
startingPosition = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseMove( MouseEvent event ) {
|
|
||||||
dragDetector.mouseMove( event );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void controlResized( ControlEvent event ) {
|
|
||||||
imageUpdate.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setForeground( Color color ) {
|
|
||||||
imageUpdate.setForeground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
Color getForeground() {
|
|
||||||
return imageUpdate.getForeground();
|
|
||||||
}
|
|
||||||
|
|
||||||
Color getBackground() {
|
|
||||||
return imageUpdate.getBackground();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBackground( Color color ) {
|
|
||||||
imageUpdate.setBackground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeControl( ) {
|
|
||||||
control.addMouseListener( this );
|
|
||||||
control.addMouseMoveListener( this );
|
|
||||||
control.addControlListener( this );
|
|
||||||
control.addDragDetectListener( this );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void mouseDoubleClick( MouseEvent event ) {}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.MouseEvent;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
|
|
||||||
// TODO [fappel]: This is a workaround for a problem described here:
|
|
||||||
// http://stackoverflow.com/questions/3908290/mousedown-events-are-not-delivered-until-mouseup-when-a-drag-source-is-present
|
|
||||||
// This seems to be related to https://bugs.eclipse.org/bugs/show_bug.cgi?id=328396
|
|
||||||
// which is resolved. As it did not work on my setup I adapted the workaround of the last
|
|
||||||
// stackoverflow answer.
|
|
||||||
|
|
||||||
public class DragDetector {
|
|
||||||
|
|
||||||
int lastMouseX;
|
|
||||||
int lastMouseY;
|
|
||||||
boolean dragEventGenerated;
|
|
||||||
|
|
||||||
private final Control control;
|
|
||||||
private final int sensibility;
|
|
||||||
|
|
||||||
public DragDetector( Control control, int sensibility ) {
|
|
||||||
this.control = control;
|
|
||||||
this.sensibility = sensibility;
|
|
||||||
this.control.setDragDetect( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseMove( MouseEvent e ) {
|
|
||||||
if( ( e.stateMask & SWT.BUTTON1 ) > 0 ) {
|
|
||||||
int deltaX = lastMouseX - e.x;
|
|
||||||
int deltaY = lastMouseY - e.y;
|
|
||||||
int dragDistance = deltaX * deltaX + deltaY * deltaY;
|
|
||||||
if( !dragEventGenerated && dragDistance > sensibility ) {
|
|
||||||
dragEventGenerated = true;
|
|
||||||
Event event = createDragEvent( e );
|
|
||||||
control.notifyListeners( SWT.DragDetect, event );
|
|
||||||
}
|
|
||||||
lastMouseX = e.x;
|
|
||||||
lastMouseY = e.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dragHandled() {
|
|
||||||
dragEventGenerated = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Event createDragEvent( MouseEvent e ) {
|
|
||||||
Event event = new Event();
|
|
||||||
event.type = SWT.DragDetect;
|
|
||||||
event.display = control.getDisplay();
|
|
||||||
event.widget = control;
|
|
||||||
event.button = e.button;
|
|
||||||
event.stateMask = e.stateMask;
|
|
||||||
event.time = e.time;
|
|
||||||
event.x = e.x;
|
|
||||||
event.y = e.y;
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import static com.minres.scviewer.database.ui.swt.sb.Direction.HORIZONTAL;
|
|
||||||
import static com.minres.scviewer.database.ui.swt.sb.ShiftData.calculateSelectionRange;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.ui.swt.sb.DragControl.DragAction;
|
|
||||||
|
|
||||||
final class DragShifter implements DragAction {
|
|
||||||
|
|
||||||
private final FlatScrollBar scrollBar;
|
|
||||||
private final int buttonLength;
|
|
||||||
|
|
||||||
public DragShifter( FlatScrollBar scrollBar, int buttonLength ) {
|
|
||||||
this.scrollBar = scrollBar;
|
|
||||||
this.buttonLength = buttonLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start() {
|
|
||||||
scrollBar.notifyListeners( SWT.DRAG );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run( int startX, int startY, int currentX, int currentY ) {
|
|
||||||
ShiftData shiftData = newShiftData( startX, startY, currentX, currentY );
|
|
||||||
if( shiftData.canShift() ) {
|
|
||||||
int selectionRange = calculateSelectionRange( scrollBar );
|
|
||||||
int selectionDelta = shiftData.calculateSelectionDelta( selectionRange );
|
|
||||||
int selection = scrollBar.getSelection() + selectionDelta;
|
|
||||||
scrollBar.setSelectionInternal( selection, SWT.DRAG );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void end() {
|
|
||||||
scrollBar.notifyListeners( SWT.NONE );
|
|
||||||
}
|
|
||||||
|
|
||||||
private ShiftData newShiftData( int startX, int startY, int currentX, int currentY ) {
|
|
||||||
ShiftData result;
|
|
||||||
if( scrollBar.direction == HORIZONTAL ) {
|
|
||||||
result = new ShiftData( buttonLength, getScrollBarSize().x, getDragSize().x, currentX - startX );
|
|
||||||
} else {
|
|
||||||
result = new ShiftData( buttonLength, getScrollBarSize().y, getDragSize().y, currentY - startY );
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point getScrollBarSize() {
|
|
||||||
return scrollBar.getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point getDragSize() {
|
|
||||||
return scrollBar.drag.getControl().getSize();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.ui.swt.sb.ClickControl.ClickAction;
|
|
||||||
|
|
||||||
class FastDecrementer implements ClickAction {
|
|
||||||
|
|
||||||
private final FlatScrollBar scrollBar;
|
|
||||||
|
|
||||||
private int x;
|
|
||||||
private int y;
|
|
||||||
|
|
||||||
FastDecrementer( FlatScrollBar scrollBar ) {
|
|
||||||
this.scrollBar = scrollBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Rectangle drag = getDragBounds();
|
|
||||||
Point mouse = getMouseLocation();
|
|
||||||
if( mouse.x <= drag.x || mouse.y <= drag.y ) {
|
|
||||||
int selection = scrollBar.getSelection() - scrollBar.getPageIncrement();
|
|
||||||
scrollBar.setSelectionInternal( selection, SWT.PAGE_UP );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCoordinates( int x, int y ) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point getMouseLocation() {
|
|
||||||
return getDisplay().map( scrollBar.upFast.getControl(), null, x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle getDragBounds() {
|
|
||||||
Rectangle dragBounds = scrollBar.drag.getControl().getBounds();
|
|
||||||
return getDisplay().map( scrollBar, null, dragBounds );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Display getDisplay() {
|
|
||||||
return scrollBar.getDisplay();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
|
|
||||||
import com.minres.scviewer.database.ui.swt.sb.ClickControl.ClickAction;
|
|
||||||
|
|
||||||
class FastIncrementer implements ClickAction {
|
|
||||||
|
|
||||||
private final FlatScrollBar scrollBar;
|
|
||||||
|
|
||||||
private Point mouse;
|
|
||||||
|
|
||||||
FastIncrementer( FlatScrollBar scrollBar ) {
|
|
||||||
this.scrollBar = scrollBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Rectangle drag = getDragBounds();
|
|
||||||
if( mouse.x > drag.x + drag.width || mouse.y > drag.y + drag.height ) {
|
|
||||||
int selection = scrollBar.getSelection() + scrollBar.getPageIncrement();
|
|
||||||
scrollBar.setSelectionInternal( selection, SWT.PAGE_DOWN );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setCoordinates( int x, int y ) {
|
|
||||||
mouse = getMouseLocation( x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Point getMouseLocation(int x, int y) {
|
|
||||||
return Display.getCurrent().map( scrollBar.downFast.getControl(), null, x, y );
|
|
||||||
}
|
|
||||||
|
|
||||||
private Rectangle getDragBounds() {
|
|
||||||
Rectangle dragBounds = scrollBar.drag.getControl().getBounds();
|
|
||||||
return Display.getCurrent().map( scrollBar, null, dragBounds );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,295 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import static com.minres.scviewer.database.ui.swt.sb.UntypedSelectionAdapter.lookup;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.SelectionEvent;
|
|
||||||
import org.eclipse.swt.events.SelectionListener;
|
|
||||||
import org.eclipse.swt.graphics.Color;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Display;
|
|
||||||
import org.eclipse.swt.widgets.Event;
|
|
||||||
import org.eclipse.swt.widgets.Layout;
|
|
||||||
import org.eclipse.swt.widgets.Listener;
|
|
||||||
|
|
||||||
public class FlatScrollBar extends Composite {
|
|
||||||
|
|
||||||
public static final int BAR_BREADTH = 6;
|
|
||||||
|
|
||||||
static final int DEFAULT_MINIMUM = 0;
|
|
||||||
static final int DEFAULT_MAXIMUM = 100;
|
|
||||||
static final int DEFAULT_INCREMENT = 1;
|
|
||||||
static final int DEFAULT_THUMB = 10;
|
|
||||||
static final int DEFAULT_PAGE_INCREMENT = DEFAULT_THUMB;
|
|
||||||
static final int DEFAULT_SELECTION = 0;
|
|
||||||
static final int DEFAULT_BUTTON_LENGTH = 0;
|
|
||||||
static final int DEFAULT_MAX_EXPANSION = Direction.CLEARANCE + 2;
|
|
||||||
|
|
||||||
final ClickControl up;
|
|
||||||
final ClickControl upFast;
|
|
||||||
final DragControl drag;
|
|
||||||
final ClickControl downFast;
|
|
||||||
final ClickControl down;
|
|
||||||
final Direction direction;
|
|
||||||
final MouseWheelShifter mouseWheelHandler;
|
|
||||||
final Collection<SelectionListener> listeners;
|
|
||||||
|
|
||||||
private int minimum;
|
|
||||||
private int maximum;
|
|
||||||
private int increment;
|
|
||||||
private int pageIncrement;
|
|
||||||
private int thumb;
|
|
||||||
private int selection;
|
|
||||||
private boolean onDrag;
|
|
||||||
private int buttonLength;
|
|
||||||
|
|
||||||
public FlatScrollBar( final Composite parent, int style ) {
|
|
||||||
this( parent, style, DEFAULT_BUTTON_LENGTH, DEFAULT_MAX_EXPANSION );
|
|
||||||
}
|
|
||||||
|
|
||||||
FlatScrollBar( Composite parent, int style, int buttonLength, int maxExpansion ) {
|
|
||||||
super( parent, SWT.NONE );
|
|
||||||
super.setLayout( new FlatScrollBarLayout( getDirection( style ) ) );
|
|
||||||
this.minimum = DEFAULT_MINIMUM;
|
|
||||||
this.maximum = DEFAULT_MAXIMUM;
|
|
||||||
this.increment = DEFAULT_INCREMENT;
|
|
||||||
this.pageIncrement = DEFAULT_PAGE_INCREMENT;
|
|
||||||
this.thumb = DEFAULT_THUMB;
|
|
||||||
this.selection = DEFAULT_SELECTION;
|
|
||||||
this.buttonLength = buttonLength;
|
|
||||||
this.direction = getDirection( style );
|
|
||||||
this.direction.setDefaultSize( this );
|
|
||||||
this.up = new ClickControl( this, new Decrementer( this ), maxExpansion );
|
|
||||||
this.upFast = new ClickControl( this, new FastDecrementer( this ), maxExpansion );
|
|
||||||
this.drag = new DragControl( this, new DragShifter( this, buttonLength ), maxExpansion );
|
|
||||||
this.downFast = new ClickControl( this, new FastIncrementer( this ), maxExpansion );
|
|
||||||
this.down = new ClickControl( this, new Incrementer( this ), maxExpansion );
|
|
||||||
this.mouseWheelHandler = new MouseWheelShifter( this, parent, buttonLength );
|
|
||||||
this.listeners = new HashSet<SelectionListener>();
|
|
||||||
addMouseTrackListener( new MouseTracker( this, maxExpansion ) );
|
|
||||||
addControlListener( new ResizeObserver( this ) );
|
|
||||||
setDefaultColorScheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLayout( Layout layout ) {
|
|
||||||
throw new UnsupportedOperationException( FlatScrollBar.class.getName() + " does not allow to change layout." );
|
|
||||||
};
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStyle() {
|
|
||||||
return direction != null ? super.getStyle() | direction.value() : super.getStyle();
|
|
||||||
};
|
|
||||||
|
|
||||||
Direction getDirection() {
|
|
||||||
return direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMinimum( int minimum ) {
|
|
||||||
if( this.minimum != minimum && minimum >= 0 && minimum < maximum ) {
|
|
||||||
this.minimum = minimum;
|
|
||||||
adjustThumb();
|
|
||||||
adjustSelection();
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinimum() {
|
|
||||||
return minimum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaximum( int maximum ) {
|
|
||||||
if( this.maximum != maximum && maximum >= 0 && maximum > minimum ) {
|
|
||||||
this.maximum = maximum;
|
|
||||||
adjustThumb();
|
|
||||||
adjustSelection();
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaximum() {
|
|
||||||
return maximum;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThumb( int thumb ) {
|
|
||||||
if( this.thumb != thumb && thumb >= 1 ) {
|
|
||||||
this.thumb = thumb;
|
|
||||||
adjustThumb();
|
|
||||||
adjustSelection();
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getThumb() {
|
|
||||||
return thumb;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIncrement( int increment ) {
|
|
||||||
if( this.increment != increment ) {
|
|
||||||
this.increment = increment;
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIncrement() {
|
|
||||||
return increment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPageIncrement( int pageIncrement ) {
|
|
||||||
this.pageIncrement = pageIncrement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPageIncrement() {
|
|
||||||
return pageIncrement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSelection( int selection ) {
|
|
||||||
if( !onDrag ) {
|
|
||||||
updateSelection( selection );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSelection() {
|
|
||||||
return selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSelectionListener( SelectionListener selectionListener ) {
|
|
||||||
listeners.add( selectionListener );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeSelectionListener( SelectionListener selectionListener ) {
|
|
||||||
listeners.remove( selectionListener );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addListener( int eventType, final Listener listener ) {
|
|
||||||
if( eventType == SWT.Selection ) {
|
|
||||||
addSelectionListener( new UntypedSelectionAdapter( listener ) );
|
|
||||||
} else {
|
|
||||||
super.addListener( eventType, listener );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeListener( int eventType, Listener listener ) {
|
|
||||||
if( eventType == SWT.Selection ) {
|
|
||||||
removeSelectionListener( lookup( listeners, listener ) );
|
|
||||||
} else {
|
|
||||||
super.removeListener( eventType, listener );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void layout() {
|
|
||||||
direction.layout( this, buttonLength );
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIncrementButtonLength( int length ) {
|
|
||||||
this.buttonLength = length;
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIncrementButtonLength() {
|
|
||||||
return buttonLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIncrementColor( Color color ) {
|
|
||||||
up.setForeground( color );
|
|
||||||
down.setForeground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color getIncrementColor() {
|
|
||||||
return up.getForeground();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPageIncrementColor( Color color ) {
|
|
||||||
upFast.setForeground( color );
|
|
||||||
downFast.setForeground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color getPageIncrementColor() {
|
|
||||||
return upFast.getForeground();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setThumbColor( Color color ) {
|
|
||||||
drag.setForeground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color getThumbColor() {
|
|
||||||
return drag.getForeground();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBackground( Color color ) {
|
|
||||||
up.setBackground( color );
|
|
||||||
upFast.setBackground( color );
|
|
||||||
drag.setBackground( color );
|
|
||||||
downFast.setBackground( color );
|
|
||||||
down.setBackground( color );
|
|
||||||
super.setBackground( color );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setSelectionInternal( int selection, int detail ) {
|
|
||||||
int oldSelection = this.selection;
|
|
||||||
updateSelection( selection );
|
|
||||||
if( oldSelection != this.selection ) {
|
|
||||||
notifyListeners( detail );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateSelection( int selection ) {
|
|
||||||
if( this.selection != selection ) {
|
|
||||||
this.selection = selection;
|
|
||||||
adjustSelection();
|
|
||||||
layout();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notifyListeners( int detail ) {
|
|
||||||
updateOnDrag( detail );
|
|
||||||
SelectionEvent selectionEvent = createEvent( detail );
|
|
||||||
for( SelectionListener listener : listeners ) {
|
|
||||||
listener.widgetSelected( selectionEvent );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateOnDrag( int detail ) {
|
|
||||||
onDrag = ( onDrag || ( SWT.DRAG & detail ) > 0 ) && ( SWT.NONE != detail );
|
|
||||||
}
|
|
||||||
|
|
||||||
private SelectionEvent createEvent( int detail ) {
|
|
||||||
Event event = new Event();
|
|
||||||
event.widget = this;
|
|
||||||
event.detail = detail;
|
|
||||||
return new SelectionEvent( event );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void adjustThumb() {
|
|
||||||
if( thumb > maximum - minimum ) {
|
|
||||||
thumb = Math.min( maximum - minimum, thumb );
|
|
||||||
thumb = Math.max( 1, thumb );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void adjustSelection() {
|
|
||||||
selection = Math.min( selection, maximum - thumb );
|
|
||||||
selection = Math.max( selection, minimum );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Direction getDirection( int style ) {
|
|
||||||
return ( style & SWT.HORIZONTAL ) > 0 ? Direction.HORIZONTAL : Direction.VERTICAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setDefaultColorScheme() {
|
|
||||||
up.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_WIDGET_NORMAL_SHADOW ) );
|
|
||||||
upFast.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND ) );
|
|
||||||
drag.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_WIDGET_FOREGROUND ) );
|
|
||||||
downFast.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_WIDGET_BACKGROUND ) );
|
|
||||||
down.setForeground( Display.getCurrent().getSystemColor( SWT.COLOR_WIDGET_NORMAL_SHADOW ) );
|
|
||||||
setBackground( getBackground() );
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package com.minres.scviewer.database.ui.swt.sb;
|
|
||||||
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Layout;
|
|
||||||
|
|
||||||
class FlatScrollBarLayout extends Layout {
|
|
||||||
|
|
||||||
private final Direction direction;
|
|
||||||
|
|
||||||
public FlatScrollBarLayout( Direction orientation ) {
|
|
||||||
this.direction = orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void layout( Composite composite, boolean flushCache ) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Point computeSize( Composite composite, int wHint, int hHint, boolean flushCache ) {
|
|
||||||
return direction.computeSize( composite, wHint, hHint, flushCache );
|
|
||||||
}
|
|
||||||
}
|
|