Compare commits
	
		
			30 Commits
		
	
	
		
			feature/he
			...
			feature/cu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7dbcffe95d | |||
| 20934a9f47 | |||
| 24890f9bbb | |||
| bd0629301b | |||
| 71da420d86 | |||
| f9be6758e2 | |||
| 93a8c067fc | |||
| 5a372d0f90 | |||
| 806000c4cc | |||
| c32d46cdc0 | |||
| 5736279e8d | |||
| e3f4dc6616 | |||
| a64e06ff7a | |||
| a42b786835 | |||
| e76000d87b | |||
| 60ead71029 | |||
| 4c48fda5ad | |||
| 6a591f2dbc | |||
| 86c30ad948 | |||
| 0ae055b486 | |||
| efcd4f5ab8 | |||
| 232d2d4275 | |||
| 44f96e5383 | |||
| 44812310b0 | |||
| 6ef91bb5e7 | |||
| aa459b0ea6 | |||
| a2adf66618 | |||
| 3405e90df9 | |||
| 9a59947e67 | |||
| 9384d3278c | 
| @@ -12,7 +12,8 @@ | ||||
|     <booleanAttribute key="M2_UPDATE_SNAPSHOTS" value="false"/> | ||||
|     <stringAttribute key="M2_USER_SETTINGS" value=""/> | ||||
|     <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"/> | ||||
|     <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}"/> | ||||
| </launchConfiguration> | ||||
|   | ||||
							
								
								
									
										17
									
								
								.project
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,17 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <projectDescription> | ||||
| 	<name>com.minres.scviewer.parent</name> | ||||
| 	<comment></comment> | ||||
| 	<projects> | ||||
| 	</projects> | ||||
| 	<buildSpec> | ||||
| 		<buildCommand> | ||||
| 			<name>org.eclipse.m2e.core.maven2Builder</name> | ||||
| 			<arguments> | ||||
| 			</arguments> | ||||
| 		</buildCommand> | ||||
| 	</buildSpec> | ||||
| 	<natures> | ||||
| 		<nature>org.eclipse.m2e.core.maven2Nature</nature> | ||||
| 	</natures> | ||||
| </projectDescription> | ||||
							
								
								
									
										62
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -30,25 +30,43 @@ Legend: | ||||
| * Mouse Scroll wheel: MScrl | ||||
| * Context any means Name List, Value List or Waveform | ||||
|  | ||||
| | Input     | Modifier | Context  | Action                            | | ||||
| |-----------|----------|----------|-----------------------------------| | ||||
| | LMB klick |          | any      | select                            | | ||||
| | LMB klick | Shift    | Waveform | move selected marker to position  | | ||||
| | LMB klick | Control  | Waveform | move cursor to position           | | ||||
| | LMB drag  |          | Waveform | zoom to range                     | | ||||
| | MMB klick |          | 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           | | ||||
| | 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                     | | ||||
|  | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <version>3.0.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.1.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.0.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.1.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <version>1.1.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <packaging>eclipse-plugin</packaging> | ||||
|   <dependencies> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ Manifest-Version: 1.0 | ||||
| Bundle-ManifestVersion: 2 | ||||
| Bundle-Name: Textual transaction database | ||||
| Bundle-SymbolicName: com.minres.scviewer.database.text | ||||
| Bundle-Version: 4.0.0.qualifier | ||||
| Bundle-Version: 4.0.1.qualifier | ||||
| Bundle-Vendor: MINRES Technologies GmbH | ||||
| Bundle-RequiredExecutionEnvironment: JavaSE-11 | ||||
| Import-Package: org.osgi.framework;version="1.3.0" | ||||
|   | ||||
| @@ -2,12 +2,12 @@ | ||||
| 	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.database.text</artifactId> | ||||
| 	<version>4.0.0-SNAPSHOT</version> | ||||
| 	<version>4.0.1-SNAPSHOT</version> | ||||
| 	<parent> | ||||
| 		<groupId>com.minres.scviewer</groupId> | ||||
| 		<artifactId>com.minres.scviewer.parent</artifactId> | ||||
| 		<version>2.14.1</version> | ||||
| 		<relativePath>../../..</relativePath> | ||||
| 		<version>2.15.1</version> | ||||
| 		<relativePath>../..</relativePath> | ||||
| 	</parent> | ||||
| 	<packaging>eclipse-plugin</packaging> | ||||
| 	 | ||||
|   | ||||
| @@ -345,10 +345,10 @@ public class TextDbLoader implements IWaveformDbLoader { | ||||
| 			String curLine = reader.readLine(); | ||||
| 			String nextLine = null; | ||||
| 			while ((nextLine = reader.readLine()) != null && curLine != null) { | ||||
| 				curLine = parseLine(curLine, nextLine); | ||||
| 				curLine = parseLine(curLine, nextLine, false); | ||||
| 			} | ||||
| 			if (curLine != null) | ||||
| 				parseLine(curLine, nextLine); | ||||
| 				parseLine(curLine, nextLine, true); | ||||
| 			for(Entry<Long, ScvTx> e: transactionById.entrySet()) { | ||||
| 				ScvTx scvTx = e.getValue(); | ||||
| 				scvTx.endTime=loader.maxTime; | ||||
| @@ -385,16 +385,16 @@ public class TextDbLoader implements IWaveformDbLoader { | ||||
| 		 * @throws IOException Signals that an I/O exception has occurred. | ||||
| 		 * @throws InputFormatException Signals that the input format is wrong | ||||
| 		 */ | ||||
| 		private String parseLine(String curLine, String nextLine) throws IOException, InputFormatException { | ||||
| 		private String parseLine(String curLine, String nextLine, boolean last) throws IOException, InputFormatException { | ||||
| 			String[] tokens = curLine.split("\\s+"); | ||||
| 			if ("tx_record_attribute".equals(tokens[0])) { | ||||
| 			if ("tx_record_attribute".equals(tokens[0]) && tokens.length>4) { | ||||
| 				Long id = Long.parseLong(tokens[1]); | ||||
| 				String name = tokens[2].substring(1, tokens[2].length()-1); | ||||
| 				DataType type = DataType.valueOf(tokens[3]); | ||||
| 				String remaining = tokens.length > 5 ? String.join(" ", Arrays.copyOfRange(tokens, 5, tokens.length)) : ""; | ||||
| 				TxAttributeType attrType = getAttrType(name, type, AssociationType.RECORD); | ||||
| 				transactionById.get(id).attributes.add(new TxAttribute(attrType, getAttrString(attrType, remaining))); | ||||
| 			} else if ("tx_begin".equals(tokens[0])) { | ||||
| 			} else if ("tx_begin".equals(tokens[0]) && tokens.length>4) { | ||||
| 				Long id = Long.parseLong(tokens[1]); | ||||
| 				Long genId = Long.parseLong(tokens[2]); | ||||
| 				TxGenerator gen = loader.txGenerators.get(genId); | ||||
| @@ -413,7 +413,7 @@ public class TextDbLoader implements IWaveformDbLoader { | ||||
| 					} | ||||
| 				} | ||||
| 				transactionById.put(id, scvTx); | ||||
| 			} else if ("tx_end".equals(tokens[0])) { | ||||
| 			} else if ("tx_end".equals(tokens[0]) && tokens.length>4) { | ||||
| 				Long id = Long.parseLong(tokens[1]); | ||||
| 				ScvTx scvTx = transactionById.get(id); | ||||
| 				assert Long.parseLong(tokens[2]) == scvTx.generatorId; | ||||
| @@ -443,7 +443,7 @@ public class TextDbLoader implements IWaveformDbLoader { | ||||
| 				} | ||||
| 				txSink.put(scvTx.getId(), scvTx); | ||||
| 				transactionById.remove(id); | ||||
| 			} else if ("tx_relation".equals(tokens[0])) { | ||||
| 			} else if ("tx_relation".equals(tokens[0]) && 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); | ||||
| @@ -483,7 +483,7 @@ public class TextDbLoader implements IWaveformDbLoader { | ||||
| 				} | ||||
| 			} else if (")".equals(tokens[0])) { | ||||
| 				generator = null; | ||||
| 			} else | ||||
| 			} else if(!last)			 | ||||
| 				throw new InputFormatException("Don't know what to do with: '" + curLine + "'"); | ||||
| 			return nextLine; | ||||
| 		} | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <version>4.0.0-SNAPSHOT</version> | ||||
| </project> | ||||
|   | ||||
| @@ -79,23 +79,17 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide | ||||
| 	 | ||||
|     public void setHighliteRelation(RelationType relationType); | ||||
|  | ||||
| 	public long getMaxTime(); | ||||
|  | ||||
| 	public void setMaxTime(long maxTime); | ||||
|  | ||||
| 	public void setZoomLevel(int scale); | ||||
|  | ||||
| 	public int getZoomLevel(); | ||||
|  | ||||
| 	public void setCursorTime(long time); | ||||
|  | ||||
| 	public void setMarkerTime(long time, int index); | ||||
| 	public void setMarkerTime(int marker, long time); | ||||
|  | ||||
| 	public long getCursorTime(); | ||||
|  | ||||
| 	public int getSelectedMarkerId(); | ||||
| 	public int getSelectedMarker(); | ||||
|  | ||||
| 	public long getMarkerTime(int index); | ||||
| 	public long getMarkerTime(int marker); | ||||
|  | ||||
| 	public void addPropertyChangeListener(PropertyChangeListener listener); | ||||
|  | ||||
| @@ -105,16 +99,8 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide | ||||
|  | ||||
| 	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener); | ||||
|  | ||||
| 	public String getScaledTime(long time); | ||||
|  | ||||
| 	public String[] getZoomLevels(); | ||||
|  | ||||
| 	public List<ICursor> getCursorList(); | ||||
|  | ||||
| 	public long getBaselineTime(); | ||||
|  | ||||
| 	public void setBaselineTime(Long scale); | ||||
| 	 | ||||
| 	public void scrollHorizontal(int percent); | ||||
| 	 | ||||
| 	public void scrollTo(int pos); | ||||
| @@ -124,4 +110,7 @@ public interface IWaveformView extends PropertyChangeListener, ISelectionProvide | ||||
| 	public void deleteSelectedTracks(); | ||||
|  | ||||
| 	public TrackEntry addWaveform(IWaveform waveform, int pos); | ||||
|  | ||||
| 	public IWaveformZoom getWaveformZoom(); | ||||
| 	 | ||||
| } | ||||
| @@ -0,0 +1,24 @@ | ||||
| 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); | ||||
| } | ||||
| @@ -0,0 +1,3 @@ | ||||
| package com.minres.scviewer.database.ui; | ||||
|  | ||||
| public enum ZoomKind {IN, OUT, FIT, FULL} | ||||
| @@ -4,8 +4,8 @@ import java.text.DecimalFormat; | ||||
|  | ||||
| public class Constants { | ||||
|  | ||||
| 	public static final String[] UNIT_STRING={"fs", "ps", "ns", "us", "ms"};//, "s"}; | ||||
| 	public static final long[]   UNIT_MULTIPLIER={1, 1000, 1000*1000, 1000*1000*1000, 1000*1000*1000*1000, 1000*1000*1000*1000*1000 }; | ||||
| 	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 long[] SCALE_MULTIPLIER={1, 2, 5, 10, 20, 50, 100, 200, 500}; | ||||
| @@ -13,22 +13,35 @@ public class Constants { | ||||
| 	public static final String CONTENT_PROVIDER_TAG = "TOOLTIP_CONTENT_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_US = new DecimalFormat("#.0#####");  | ||||
| 	public static final DecimalFormat TIME_FORMAT_MS = new DecimalFormat("#.0#####");  | ||||
| 	 | ||||
| 	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 level) { | ||||
| 		switch(level/SCALE_MULTIPLIER.length) { | ||||
| 	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; | ||||
| 		case 3:	return TIME_FORMAT_US; | ||||
| 		case 4:	return TIME_FORMAT_MS; | ||||
| 		default: | ||||
| 			return TIME_FORMAT_FS; | ||||
| 			return TIME_FORMAT_UMS; | ||||
| 		} | ||||
| 	} | ||||
| 	private Constants() {} | ||||
|   | ||||
| @@ -13,6 +13,7 @@ package com.minres.scviewer.database.ui.swt; | ||||
| import org.eclipse.core.runtime.IStatus; | ||||
| import org.eclipse.core.runtime.Plugin; | ||||
| import org.eclipse.core.runtime.Status; | ||||
| import org.eclipse.wb.swt.SWTResourceManager; | ||||
| import org.osgi.framework.BundleContext; | ||||
|  | ||||
| public class DatabaseUiPlugin extends Plugin { | ||||
| @@ -24,6 +25,7 @@ public class DatabaseUiPlugin extends Plugin { | ||||
|  | ||||
| 	@Override | ||||
| 	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...")); | ||||
| 	} | ||||
| } | ||||
| @@ -75,7 +75,7 @@ public class ArrowPainter implements IPainter { | ||||
| 		this.tx = newTx; | ||||
| 		iRect = new LinkedList<>(); | ||||
| 		oRect = new LinkedList<>(); | ||||
| 		scaleFactor = waveCanvas.getScaleFactor(); | ||||
| 		scaleFactor = waveCanvas.getScale(); | ||||
| 		if (tx != null) { | ||||
| 			calculateGeometries(); | ||||
| 		} | ||||
| @@ -133,7 +133,7 @@ public class ArrowPainter implements IPainter { | ||||
| 		Color highliteColor = waveCanvas.styleProvider.getColor(WaveformColors.REL_ARROW_HIGHLITE); | ||||
|  | ||||
| 		if(tx==null) return; | ||||
| 		scaleFactor = waveCanvas.getScaleFactor(); | ||||
| 		scaleFactor = waveCanvas.getScale(); | ||||
| 		if(calculateGeometries()) | ||||
| 			return; | ||||
| 		int correctionValue = (int)(selectionOffset); | ||||
|   | ||||
| @@ -15,7 +15,6 @@ import org.eclipse.swt.graphics.Rectangle; | ||||
|  | ||||
| import com.minres.scviewer.database.ui.ICursor; | ||||
| import com.minres.scviewer.database.ui.WaveformColors; | ||||
| import com.minres.scviewer.database.ui.swt.Constants; | ||||
|  | ||||
| public class CursorPainter implements IPainter, ICursor { | ||||
|  | ||||
| @@ -66,7 +65,7 @@ public class CursorPainter implements IPainter, ICursor { | ||||
| 		Rectangle area = proj.unProject(clientRect); | ||||
| 		if(!waveCanvas.painterList.isEmpty()){ | ||||
| 			 | ||||
| 			long scaleFactor=waveCanvas.getScaleFactor(); | ||||
| 			long scaleFactor=waveCanvas.getScale(); | ||||
| 			long beginPos = area.x; | ||||
| 			 | ||||
| 			maxPosX = area.x + area.width; | ||||
| @@ -84,8 +83,7 @@ public class CursorPainter implements IPainter, ICursor { | ||||
| 				proj.drawLine(x, top, x, area.y+area.height); | ||||
| 				proj.setBackground(drawColor); | ||||
| 				proj.setForeground(textColor); | ||||
| 				double dTime=time; | ||||
| 				proj.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(dTime/waveCanvas.getScaleFactorPow10())+waveCanvas.getUnitStr(), x+1, top); | ||||
| 				proj.drawText(waveCanvas.timeToString(time), x+1, top); | ||||
| 			} | ||||
| 		} | ||||
| 	}	 | ||||
|   | ||||
| @@ -13,6 +13,7 @@ package com.minres.scviewer.database.ui.swt.internal; | ||||
| import org.eclipse.swt.SWT; | ||||
| import org.eclipse.swt.graphics.Color; | ||||
| import org.eclipse.swt.graphics.GC; | ||||
| import org.eclipse.swt.graphics.Point; | ||||
| import org.eclipse.swt.graphics.Rectangle; | ||||
| import org.eclipse.wb.swt.SWTResourceManager; | ||||
|  | ||||
| @@ -37,26 +38,26 @@ public class RulerPainter implements IPainter { | ||||
|     	Color headerBgColor = waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND); | ||||
|     	if(headerBgColor.isDisposed()) | ||||
|     		headerBgColor=SWTResourceManager.getColor(255,255,255); | ||||
|         String unit=waveCanvas.getUnitStr(); | ||||
|         long unitMultiplier=waveCanvas.getUnitMultiplier(); | ||||
|         long scaleFactor=waveCanvas.getScaleFactor(); | ||||
|  | ||||
|         long startPos=area.x*scaleFactor;  | ||||
|         long startVal=startPos - proj.getTranslation().x*scaleFactor; | ||||
|         long endPos=startPos+area.width*scaleFactor; | ||||
|  | ||||
|         long rulerTickMinor = RULER_TICK_MINOR*scaleFactor; | ||||
|         long rulerTickMajor = RULER_TICK_MAJOR*scaleFactor; | ||||
|     	 | ||||
|         long scaleFactor=waveCanvas.getScale(); | ||||
|         long startTime=waveCanvas.getMinVisibleTime();  | ||||
|         long endTime=waveCanvas.getMaxVisibleTime(); | ||||
|  | ||||
|         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 majorTickY = waveCanvas.rulerHeight-15; | ||||
|         int textY=waveCanvas.rulerHeight-30; | ||||
|         int baselineY=waveCanvas.rulerHeight - 1; | ||||
|         int bottom=waveCanvas.rulerHeight - 2; | ||||
|  | ||||
|         long modulo = startVal % rulerTickMinor; | ||||
|         long startMinorIncrPos = startPos+rulerTickMinor-modulo; | ||||
|         long startMinorIncrVal = startVal+rulerTickMinor-modulo; | ||||
|         long startTickTime = startTime+rulerTickMinor-(startTime % rulerTickMinor); | ||||
|         long majorTickDist = rulerTickMajor/scaleFactor; | ||||
|          | ||||
|         gc.setBackground(waveCanvas.getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); | ||||
|         gc.fillRectangle(new Rectangle(area.x, area.y, area.width, waveCanvas.rulerHeight)); | ||||
| @@ -64,20 +65,20 @@ public class RulerPainter implements IPainter { | ||||
|         gc.fillRectangle(new Rectangle(area.x, area.y, area.width, baselineY)); | ||||
|         gc.setForeground(headerFgColor); | ||||
|         gc.drawLine(area.x, area.y+bottom, area.x+area.width, area.y+bottom); | ||||
|         boolean allMarker=true; | ||||
|         for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) { | ||||
|             if ((tick % rulerTickMajor) == 0) { | ||||
|             	String text = Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).format(tick/scaleFactor*unitMultiplier); | ||||
|             	if(text.length()>8) allMarker=false; | ||||
|         int maxTextLength=0; | ||||
|         for (long tickTime = startTickTime; tickTime < endTime; tickTime+= rulerTickMinor) { | ||||
|             if ((tickTime % rulerTickMajor) == 0) { | ||||
|             	Point textSize = gc.textExtent(waveCanvas.timeToString(tickTime)); | ||||
|             	maxTextLength=textSize.x>maxTextLength?textSize.x:maxTextLength; | ||||
|             } | ||||
|         } | ||||
|         boolean drawText = true; | ||||
|         for (long pos = startMinorIncrPos, tick = startMinorIncrVal; pos < endPos; pos+= rulerTickMinor, tick += rulerTickMinor) { | ||||
|             int x0Pos = (int) (pos/scaleFactor); | ||||
|             long x0Val = tick/scaleFactor; | ||||
|             if ((tick % rulerTickMajor) == 0) { | ||||
|             	if(allMarker || drawText) | ||||
|             		gc.drawText(Constants.getTimeFormatForLevel(waveCanvas.getZoomLevel()).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); | ||||
|                 drawText=!drawText; | ||||
|             } else { | ||||
|   | ||||
| @@ -82,7 +82,7 @@ public class SignalPainter extends TrackPainter { | ||||
| 	} | ||||
|  | ||||
| 	private int getXPosEnd(long time) { | ||||
| 		long ltmp = time / this.waveCanvas.getScaleFactor(); | ||||
| 		long ltmp = time / this.waveCanvas.getScale(); | ||||
| 		return ltmp > maxPosX ? maxPosX : (int) ltmp; | ||||
| 	} | ||||
| 	 | ||||
| @@ -95,7 +95,7 @@ public class SignalPainter extends TrackPainter { | ||||
| 		proj.setFillRule(SWT.FILL_EVEN_ODD); | ||||
| 		proj.fillRectangle(area); | ||||
|  | ||||
| 		long scaleFactor = this.waveCanvas.getScaleFactor(); | ||||
| 		long scaleFactor = this.waveCanvas.getScale(); | ||||
| 		long beginPos = area.x; | ||||
| 		long beginTime = beginPos*scaleFactor; | ||||
|         long endTime = beginTime + area.width*scaleFactor; | ||||
| @@ -114,7 +114,7 @@ public class SignalPainter extends TrackPainter { | ||||
| 		yOffsetT = this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y; | ||||
| 		yOffsetM = this.waveCanvas.styleProvider.getTrackHeight() / 2 + area.y; | ||||
| 		yOffsetB = 4 * this.waveCanvas.styleProvider.getTrackHeight() / 5 + area.y; | ||||
| 		int xSigChangeBeginVal = Math.max(area.x, (int) (left.time / this.waveCanvas.getScaleFactor())); | ||||
| 		int xSigChangeBeginVal = Math.max(area.x, (int) (left.time / this.waveCanvas.getScale())); | ||||
| 		int xSigChangeBeginPos = area.x; | ||||
| 		int xSigChangeEndPos = Math.max(area.x, getXPosEnd(right.time)); | ||||
| 		 | ||||
| @@ -127,7 +127,7 @@ public class SignalPainter extends TrackPainter { | ||||
| 				right.time = endTime; | ||||
| 			} else { | ||||
| 				multiple = true; | ||||
| 				long eTime = (xSigChangeBeginVal + 1) * this.waveCanvas.getScaleFactor(); | ||||
| 				long eTime = (xSigChangeBeginVal + 1) * this.waveCanvas.getScale(); | ||||
| 				right.set(entries.floorEntry(eTime), endTime); | ||||
| 				right.time = eTime; | ||||
| 			} | ||||
| @@ -147,7 +147,7 @@ public class SignalPainter extends TrackPainter { | ||||
| 			multiple = false; | ||||
| 			if (xSigChangeEndPos == xSigChangeBeginPos) { | ||||
| 				multiple = true; | ||||
| 				long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScaleFactor(); | ||||
| 				long eTime = (xSigChangeBeginPos + 1) * this.waveCanvas.getScale(); | ||||
| 				EventEntry entry = entries.floorEntry(eTime); | ||||
| 				if(entry!=null && entry.timestamp> right.time) | ||||
| 					right.set(entry, endTime); | ||||
|   | ||||
| @@ -67,7 +67,7 @@ public class StreamPainter extends TrackPainter{ | ||||
| 		proj.setFillRule(SWT.FILL_EVEN_ODD); | ||||
| 		proj.fillRectangle(area); | ||||
|  | ||||
| 		long scaleFactor = this.waveCanvas.getScaleFactor(); | ||||
| 		long scaleFactor = this.waveCanvas.getScale(); | ||||
| 		long beginPos = area.x; | ||||
| 		long beginTime = beginPos*scaleFactor; | ||||
| 		long endTime = beginTime + area.width*scaleFactor; | ||||
| @@ -130,8 +130,8 @@ public class StreamPainter extends TrackPainter{ | ||||
|  | ||||
| 		int offset = concurrencyIndex*this.waveCanvas.styleProvider.getTrackHeight(); | ||||
| 		Rectangle bb = new Rectangle( | ||||
| 				(int)(tx.getBeginTime()/this.waveCanvas.getScaleFactor()), area.y+offset+txBase, | ||||
| 				(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScaleFactor()), txHeight); | ||||
| 				(int)(tx.getBeginTime()/this.waveCanvas.getScale()), area.y+offset+txBase, | ||||
| 				(int)((tx.getEndTime()-tx.getBeginTime())/this.waveCanvas.getScale()), txHeight); | ||||
|  | ||||
| 		if(bb.x+bb.width<area.x || bb.x>area.x+area.width) return; | ||||
| 		if(bb.width==0){ | ||||
| @@ -155,7 +155,7 @@ public class StreamPainter extends TrackPainter{ | ||||
|  | ||||
| 	public ITx getClicked(Point point) { | ||||
| 		int lane=point.y/waveCanvas.styleProvider.getTrackHeight(); | ||||
| 		EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScaleFactor()); | ||||
| 		EventEntry firstTx=stream.getEvents().floorEntry(point.x*waveCanvas.getScale()); | ||||
| 		if(firstTx!=null){ | ||||
| 			do { | ||||
| 				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) { | ||||
| 		long timePoint=offset*waveCanvas.getScaleFactor(); | ||||
| 		long timePointLow=(offset-5)*waveCanvas.getScaleFactor(); | ||||
| 		long timePointHigh=(offset+5)*waveCanvas.getScaleFactor(); | ||||
| 		long timePoint=offset*waveCanvas.getScale(); | ||||
| 		long timePointLow=(offset-5)*waveCanvas.getScale(); | ||||
| 		long timePointHigh=(offset+5)*waveCanvas.getScale(); | ||||
| 		for(IEvent e:firstTx){ | ||||
| 			if(e instanceof ITxEvent) { | ||||
| 				ITxEvent evt = (ITxEvent) e; | ||||
|   | ||||
| @@ -19,7 +19,7 @@ import org.eclipse.swt.graphics.Rectangle; | ||||
| import com.minres.scviewer.database.ui.WaveformColors; | ||||
|  | ||||
| public class TrackAreaPainter implements IPainter { | ||||
| 	 | ||||
|  | ||||
| 	/** | ||||
| 	 *  | ||||
| 	 */ | ||||
| @@ -35,14 +35,15 @@ public class TrackAreaPainter implements IPainter { | ||||
| 	} | ||||
|  | ||||
| 	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)); | ||||
| 	    proj.setBackground(this.waveCanvas.styleProvider.getColor(WaveformColors.TRACK_BG_EVEN)); | ||||
| 	    proj.setFillRule(SWT.FILL_EVEN_ODD); | ||||
| 	    proj.fillRectangle(area); | ||||
| 		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.setFillRule(SWT.FILL_EVEN_ODD); | ||||
| 		proj.fillRectangle(area); | ||||
| 		if(trackVerticalOffset.size()>0){ | ||||
| 			Integer firstKey=trackVerticalOffset.floorKey(area.y); | ||||
| 			if(firstKey==null) firstKey=trackVerticalOffset.firstKey(); | ||||
| 			Integer lastKey = trackVerticalOffset.floorKey(area.y+area.height); | ||||
| 			//if(lastKey==null) lastKey= trackVerticalOffset.lastKey(); | ||||
| 			Rectangle subArea = new Rectangle(area.x, 0, area.width, 0); | ||||
| 			if(lastKey.equals(firstKey)){ | ||||
| 				subArea.y=firstKey; | ||||
| @@ -61,9 +62,9 @@ public class TrackAreaPainter implements IPainter { | ||||
|  | ||||
| 	public void addTrackPainter(IWaveformPainter trackPainter){ | ||||
| 		trackVerticalOffset.put(trackPainter.getVerticalOffset()+waveCanvas.rulerHeight, trackPainter); | ||||
| 		 | ||||
|  | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	public int getHeight(){ | ||||
| 		if(trackVerticalOffset.size()==0) return 1; | ||||
| 		return trackVerticalOffset.lastKey() + trackVerticalOffset.lastEntry().getValue().getHeight(); | ||||
|   | ||||
| @@ -89,8 +89,9 @@ import com.minres.scviewer.database.ui.GotoDirection; | ||||
| import com.minres.scviewer.database.ui.ICursor; | ||||
| import com.minres.scviewer.database.ui.IWaveformStyleProvider; | ||||
| 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.swt.Constants; | ||||
| import com.minres.scviewer.database.ui.swt.internal.slider.ZoomBar; | ||||
|  | ||||
| public class WaveformView implements IWaveformView { | ||||
|  | ||||
| @@ -112,6 +113,10 @@ public class WaveformView implements IWaveformView { | ||||
|  | ||||
| 	private final Canvas valueList; | ||||
|  | ||||
| 	private final Control nameFill; | ||||
| 	 | ||||
| 	private final Control valueFill; | ||||
|  | ||||
| 	final WaveformCanvas waveformCanvas; | ||||
|  | ||||
| 	final ToolTipHandler toolTipHandler; | ||||
| @@ -122,12 +127,6 @@ public class WaveformView implements IWaveformView { | ||||
|  | ||||
| 	protected ObservableList<TrackEntry> streams; | ||||
|  | ||||
| 	private boolean waveformsContainTx=false; | ||||
| 	 | ||||
| 	public boolean isWaveformsContainTx() { | ||||
| 		return waveformsContainTx; | ||||
| 	} | ||||
|  | ||||
| 	int selectedMarker = 0; | ||||
|  | ||||
| 	private int tracksVerticalHeight; | ||||
| @@ -166,8 +165,7 @@ public class WaveformView implements IWaveformView { | ||||
| 									: streams.subList(firstIdx, lastIdx + 1); | ||||
| 							setSelection(new StructuredSelection(res), (e.stateMask & SWT.CTRL) != 0, false); | ||||
| 						} else | ||||
| 							setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, | ||||
| 							false); | ||||
| 							setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false); | ||||
| 					} else { | ||||
| 						setSelection(new StructuredSelection(entry.getValue()), (e.stateMask & SWT.CTRL) != 0, false); | ||||
| 					} | ||||
| @@ -209,41 +207,17 @@ public class WaveformView implements IWaveformView { | ||||
| 					asyncUpdate(e.widget); | ||||
| 					long startTime = waveformCanvas.getTimeForOffset(start.x); | ||||
| 					long endTime = waveformCanvas.getTimeForOffset(end.x); | ||||
| 					long targetTimeRange = endTime - startTime; | ||||
| 					long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime(); | ||||
| 					if (targetTimeRange == 0) | ||||
| 						return; | ||||
| 					long relation = currentTimeRange / targetTimeRange; | ||||
| 					long i = 1; | ||||
| 					int level = 0; | ||||
| 					do { | ||||
| 						if (relation < 0) { | ||||
| 							if (-relation < i) { | ||||
| 								break; | ||||
| 							} | ||||
| 							level--; | ||||
| 							if (-relation < i * 3) { | ||||
| 								break; | ||||
| 							} | ||||
| 							level--; | ||||
| 						} else { | ||||
| 							if (relation < i) { | ||||
| 								break; | ||||
| 							} | ||||
| 							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); | ||||
| 					if(startTime<endTime) { | ||||
| 						waveformCanvas.setVisibleRange(startTime, endTime); | ||||
| 					} else if(start.x!=end.x){ | ||||
| 						long targetTimeRange = startTime-endTime; | ||||
| 						long currentTimeRange = waveformCanvas.getMaxVisibleTime() - waveformCanvas.getMinVisibleTime(); | ||||
| 						long factor = currentTimeRange/targetTimeRange *waveformCanvas.getScale(); | ||||
| 						waveformCanvas.setScalingFactor(factor, (startTime+endTime)/2); | ||||
| 												 | ||||
| 					} | ||||
| 				} else if( isShift) { // set marker (button 1 and shift) | ||||
| 					setMarkerTime(snapOffsetToEvent(start), selectedMarker); | ||||
| 					setMarkerTime(selectedMarker, snapOffsetToEvent(start)); | ||||
| 				} else if(isCtrl) {	// set cursor (button 1 and ctrl) | ||||
| 					setCursorTime(snapOffsetToEvent(start)); | ||||
| 				} else { // set cursor (button 1 only) | ||||
| @@ -255,14 +229,14 @@ public class WaveformView implements IWaveformView { | ||||
| 					} | ||||
| 				} | ||||
| 			} else if (e.button == 2) { // set marker (button 2) | ||||
| 				setMarkerTime(snapOffsetToEvent(start), selectedMarker); | ||||
| 				setMarkerTime(selectedMarker, snapOffsetToEvent(start)); | ||||
| 			} | ||||
| 			asyncUpdate(e.widget); | ||||
| 		} | ||||
|  | ||||
| 		protected long snapOffsetToEvent(Point p) { | ||||
| 			long time = waveformCanvas.getTimeForOffset(p.x); | ||||
| 			long scaling = 5 * waveformCanvas.getScaleFactor(); | ||||
| 			long scaling = 5 * waveformCanvas.getScale(); | ||||
| 			for (Object o : waveformCanvas.getElementsAt(p)) { | ||||
| 				EventEntry floorEntry = null; | ||||
| 				EventEntry ceilEntry = null; | ||||
| @@ -295,8 +269,27 @@ public class WaveformView implements IWaveformView { | ||||
| 		@Override | ||||
| 		public void handleEvent(Event e) { | ||||
| 			switch (e.type) { | ||||
| 			//			case SWT.MouseWheel: | ||||
| 			//				break; | ||||
| 			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; | ||||
| 			case SWT.MouseDown: | ||||
| 				start = new Point(e.x, e.y); | ||||
| 				end = new Point(e.x, e.y); | ||||
| @@ -355,8 +348,26 @@ public class WaveformView implements IWaveformView { | ||||
| 		rightSash.setBackground(SWTResourceManager.getColor(SWT.COLOR_GRAY)); | ||||
|  | ||||
| 		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 | ||||
| 		createTextPane(namePane, "Name"); | ||||
|  | ||||
| @@ -372,7 +383,10 @@ public class WaveformView implements IWaveformView { | ||||
| 			@Override | ||||
| 			public void controlResized(ControlEvent e) { | ||||
| 				nameListScrolled.getVerticalBar().setVisible(false); | ||||
|  | ||||
| 				if(nameListScrolled.getSize().y == nameList.getSize().y) { | ||||
| 					((GridData)nameFill.getLayoutData()).heightHint=18; | ||||
| 					namePane.layout(); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 		nameList = new Canvas(nameListScrolled, SWT.NONE) { | ||||
| @@ -391,7 +405,8 @@ public class WaveformView implements IWaveformView { | ||||
| 		}); | ||||
| 		nameList.addMouseListener(nameValueMouseListener); | ||||
| 		nameListScrolled.setContent(nameList); | ||||
|  | ||||
| 		nameFill = createFill(namePane); | ||||
| 		 | ||||
| 		createTextPane(valuePane, "Value"); | ||||
|  | ||||
| 		valuePane.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_BACKGROUND)); | ||||
| @@ -404,7 +419,10 @@ public class WaveformView implements IWaveformView { | ||||
| 			@Override | ||||
| 			public void controlResized(ControlEvent e) { | ||||
| 				valueListScrolled.getVerticalBar().setVisible(false); | ||||
|  | ||||
| 				if(valueListScrolled.getSize().y == valueList.getSize().y) { | ||||
| 					((GridData)valueFill.getLayoutData()).heightHint=18; | ||||
| 					valuePane.layout(); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 		valueList = new Canvas(valueListScrolled, SWT.NONE) { | ||||
| @@ -423,6 +441,7 @@ public class WaveformView implements IWaveformView { | ||||
| 		}); | ||||
| 		valueList.addMouseListener(nameValueMouseListener); | ||||
| 		valueListScrolled.setContent(valueList); | ||||
| 		valueFill = createFill(valuePane); | ||||
|  | ||||
| 		waveformCanvas.setMaxTime(1); | ||||
| 		waveformCanvas.addPaintListener(waveformMouseListener); | ||||
| @@ -469,6 +488,26 @@ public class WaveformView implements IWaveformView { | ||||
|  | ||||
| 		toolTipHandler = new ToolTipHandler(parent.getShell()); | ||||
| 		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) { | ||||
| @@ -518,7 +557,6 @@ public class WaveformView implements IWaveformView { | ||||
| 		boolean even = true; | ||||
| 		TextLayout tl = new TextLayout(waveformCanvas.getDisplay()); | ||||
| 		tl.setFont(styleProvider.getNameFont()); | ||||
| 		waveformsContainTx=false; | ||||
| 		for (TrackEntry streamEntry : streams) { | ||||
| 			streamEntry.height = styleProvider.getTrackHeight(); | ||||
| 			streamEntry.vOffset = tracksVerticalHeight; | ||||
| @@ -526,7 +564,6 @@ public class WaveformView implements IWaveformView { | ||||
| 				streamEntry.currentValue = ""; | ||||
| 				streamEntry.height *= streamEntry.waveform.getRowCount(); | ||||
| 				painter = new StreamPainter(waveformCanvas, even, streamEntry); | ||||
| 				waveformsContainTx=true; | ||||
| 			} else if (streamEntry.waveform.getType() == WaveformType.SIGNAL) { | ||||
| 				streamEntry.currentValue = "---"; | ||||
| 				painter = new SignalPainter(waveformCanvas, even, streamEntry); | ||||
| @@ -538,7 +575,7 @@ public class WaveformView implements IWaveformView { | ||||
| 			tracksVerticalHeight += streamEntry.height; | ||||
| 			even = !even; | ||||
| 		} | ||||
| 		waveformCanvas.syncScrollBars(); | ||||
| 		waveformCanvas.syncSb(); | ||||
| 		nameList.setSize(nameMaxWidth + 15, tracksVerticalHeight); | ||||
| 		nameListScrolled.setMinSize(nameMaxWidth + 15, tracksVerticalHeight); | ||||
| 		nameList.redraw(); | ||||
| @@ -762,27 +799,30 @@ public class WaveformView implements IWaveformView { | ||||
| 				if (!add) | ||||
| 					currentWaveformSelection.clear(); | ||||
| 				List<?> selList = sel.toList(); | ||||
| 				if (selList.get(0) instanceof ITx) { | ||||
| 					ITx txSel = (ITx) selList.get(0); | ||||
| 					TrackEntry trackEntry = selList.size() == 2 && selList.get(1) instanceof TrackEntry | ||||
| 							? (TrackEntry) selList.get(1) | ||||
| 									: null; | ||||
| 					if (trackEntry == null) { | ||||
| 						trackEntry = getEntryFor(txSel); | ||||
| 						if (trackEntry == null && addIfNeeded) { | ||||
| 							trackEntry = new TrackEntry(txSel.getStream(), styleProvider); | ||||
| 							streams.add(trackEntry); | ||||
| 				for(Object o: selList) { | ||||
| 					if (o instanceof ITx) { | ||||
| 						ITx txSel = (ITx) o; | ||||
| 						TrackEntry trackEntry = selList.size() == 2 && selList.get(1) instanceof TrackEntry | ||||
| 								? (TrackEntry) selList.get(1) | ||||
| 										: null; | ||||
| 						if (trackEntry == null) { | ||||
| 							trackEntry = getEntryFor(txSel); | ||||
| 							if (trackEntry == null && addIfNeeded) { | ||||
| 								trackEntry = new TrackEntry(txSel.getStream(), styleProvider); | ||||
| 								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 { | ||||
| @@ -1125,16 +1165,6 @@ public class WaveformView implements IWaveformView { | ||||
| 		this.waveformCanvas.setHighliteRelation(relationType); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * (non-Javadoc) | ||||
| 	 *  | ||||
| 	 * @see com.minres.scviewer.database.swt.IWaveformPanel#getMaxTime() | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public long getMaxTime() { | ||||
| 		return waveformCanvas.getMaxTime(); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * (non-Javadoc) | ||||
| 	 *  | ||||
| @@ -1145,31 +1175,6 @@ public class WaveformView implements IWaveformView { | ||||
| 		this.waveformCanvas.setMaxTime(maxTime); | ||||
| 	} | ||||
|  | ||||
| 	/* | ||||
| 	 * (non-Javadoc) | ||||
| 	 *  | ||||
| 	 * @see com.minres.scviewer.database.swt.IWaveformPanel#setZoomLevel(int) | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public void setZoomLevel(int scale) { | ||||
| 		if(scale<-1) { | ||||
| 			waveformCanvas.setZoomLevel(scale, getMarkerTime(selectedMarker)); | ||||
| 		} else { | ||||
| 			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) | ||||
| 	 *  | ||||
| @@ -1188,10 +1193,10 @@ public class WaveformView implements IWaveformView { | ||||
| 	 * @see com.minres.scviewer.database.swt.IWaveformPanel#setMarkerTime(long, int) | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public void setMarkerTime(long time, int index) { | ||||
| 		if (waveformCanvas.getCursorPainters().size() > index + 1) { | ||||
| 			final Long oldVal = waveformCanvas.getCursorPainters().get(1 + index).getTime(); | ||||
| 			waveformCanvas.getCursorPainters().get(1 + index).setTime(time); | ||||
| 	public void setMarkerTime(int marker, long time) { | ||||
| 		if (waveformCanvas.getCursorPainters().size() > marker + 1) { | ||||
| 			final Long oldVal = waveformCanvas.getCursorPainters().get(1 + marker).getTime(); | ||||
| 			waveformCanvas.getCursorPainters().get(1 + marker).setTime(time); | ||||
| 			pcs.firePropertyChange(MARKER_PROPERTY, oldVal, time); | ||||
| 		} | ||||
| 	} | ||||
| @@ -1212,7 +1217,7 @@ public class WaveformView implements IWaveformView { | ||||
| 	 * @see com.minres.scviewer.database.swt.IWaveformPanel#getActMarkerTime() | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public int getSelectedMarkerId() { | ||||
| 	public int getSelectedMarker() { | ||||
| 		return selectedMarker; | ||||
| 	} | ||||
|  | ||||
| @@ -1464,58 +1469,16 @@ public class WaveformView implements IWaveformView { | ||||
| 		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(Constants.getTimeFormatForLevel(waveformCanvas.getZoomLevel()).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.SCALE_MULTIPLIER.length * Constants.UNIT_STRING.length]; | ||||
| 		int index = 0; | ||||
| 		for (String unit : Constants.UNIT_STRING) { | ||||
| 			for (long factor : Constants.SCALE_MULTIPLIER) { | ||||
| 				res[index++] = Long.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 | ||||
| 	public void scrollHorizontal(int percent) { | ||||
| 		if (percent < -100) | ||||
| 			percent = -100; | ||||
| 		if (percent > 100) | ||||
| 			percent = 100; | ||||
| 		int diff = (waveformCanvas.getWidth() * percent) / 100; | ||||
| 		Point o = waveformCanvas.getOrigin(); | ||||
| 		waveformCanvas.setOrigin(o.x - diff, o.y); | ||||
| 		waveformCanvas.redraw(); | ||||
| 		long minTime = waveformCanvas.getMinVisibleTime(); | ||||
| 		long duration = waveformCanvas.getMaxVisibleTime()-minTime; | ||||
| 		long diff = (duration * percent) / 100; | ||||
| 		waveformCanvas.setMinVisibleTime(minTime+diff); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| @@ -1563,4 +1526,13 @@ public class WaveformView implements IWaveformView { | ||||
| 			getStreamList().add(idx, e); | ||||
| 		return e; | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean waveformsContainsTx() { | ||||
| 		return  streams.stream().filter(e -> e.waveform.getType() == WaveformType.TRANSACTION).findFirst().isPresent(); | ||||
| 	} | ||||
|  | ||||
| 	@Override | ||||
| 	public IWaveformZoom getWaveformZoom() { | ||||
| 		return waveformCanvas; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,35 @@ | ||||
| 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 ); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,192 @@ | ||||
| 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; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,631 @@ | ||||
| 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(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,48 @@ | ||||
| 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; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,74 @@ | ||||
| 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; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,127 @@ | ||||
| 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(); | ||||
| 	} | ||||
| } | ||||
| After Width: | Height: | Size: 352 B | 
| After Width: | Height: | Size: 326 B | 
| After Width: | Height: | Size: 352 B | 
| After Width: | Height: | Size: 305 B | 
| After Width: | Height: | Size: 302 B | 
| After Width: | Height: | Size: 339 B | 
| After Width: | Height: | Size: 350 B | 
| After Width: | Height: | Size: 336 B | 
| After Width: | Height: | Size: 352 B | 
| After Width: | Height: | Size: 329 B | 
| After Width: | Height: | Size: 326 B | 
| After Width: | Height: | Size: 349 B | 
| @@ -0,0 +1,18 @@ | ||||
| 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 ); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,45 @@ | ||||
| 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; | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,98 @@ | ||||
| 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 ) {} | ||||
| } | ||||
| @@ -0,0 +1,105 @@ | ||||
| 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; | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,24 @@ | ||||
| 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 ) { | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,203 @@ | ||||
| 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 ); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,105 @@ | ||||
| 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 ) {} | ||||
| } | ||||
| @@ -0,0 +1,60 @@ | ||||
| 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; | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,59 @@ | ||||
| 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(); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,49 @@ | ||||
| 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(); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,42 @@ | ||||
| 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 ); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,295 @@ | ||||
| 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() ); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,23 @@ | ||||
| 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 ); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,109 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import static java.lang.Math.min; | ||||
|  | ||||
| import org.eclipse.swt.SWT; | ||||
| import org.eclipse.swt.graphics.Color; | ||||
| import org.eclipse.swt.graphics.GC; | ||||
| import org.eclipse.swt.graphics.Image; | ||||
| import org.eclipse.swt.widgets.Display; | ||||
|  | ||||
| class ImageDrawer { | ||||
|  | ||||
|   static final String IMAGE_DRAWER_IS_DISPOSED = "ImageDrawer is disposed."; | ||||
|  | ||||
|   private final int maxExpansion; | ||||
|  | ||||
|   private Color background; | ||||
|   private Color foreground; | ||||
|  | ||||
|   ImageDrawer( int expansion  ) { | ||||
|     this( expansion, getSystemColor( SWT.COLOR_WIDGET_DARK_SHADOW ), getSystemColor( SWT.COLOR_LIST_BACKGROUND ) ); | ||||
|   } | ||||
|  | ||||
|   ImageDrawer( int expansion, Color background, Color foreground ) { | ||||
|     this.maxExpansion = expansion; | ||||
|     this.foreground = defensiveCopy( background ); | ||||
|     this.background = defensiveCopy( foreground ); | ||||
|   } | ||||
|  | ||||
|   void setForeground( Color foreground ) { | ||||
|     checkDisposed(); | ||||
|     if( foreground != null ) { | ||||
|       this.foreground = prepareColorAttribute( this.foreground, foreground ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Color getForeground() { | ||||
|     checkDisposed(); | ||||
|     return foreground; | ||||
|   } | ||||
|  | ||||
|   void setBackground( Color background ) { | ||||
|     checkDisposed(); | ||||
|     if( background != null ) { | ||||
|       this.background = prepareColorAttribute( this.background, background ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Color getBackground() { | ||||
|     checkDisposed(); | ||||
|     return background; | ||||
|   } | ||||
|  | ||||
|   Image draw( int width, int height ) { | ||||
|     checkDisposed(); | ||||
|     Image result = new Image( getDisplay(), width, height ); | ||||
|     GC gc = new GC( result ); | ||||
|     try { | ||||
|       draw( gc, width, height ); | ||||
|     } finally { | ||||
|       gc.dispose(); | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   boolean isDisposed() { | ||||
|     return background.isDisposed(); | ||||
|   } | ||||
|  | ||||
|   void dispose() { | ||||
|     if( !isDisposed() ) { | ||||
|       this.background.dispose(); | ||||
|       this.foreground.dispose(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private void draw( GC gc, int width, int height ) { | ||||
|     gc.setBackground( background ); | ||||
|     gc.fillRectangle( 0, 0, width, height ); | ||||
|     gc.setBackground( foreground ); | ||||
|     gc.setAdvanced( true ); | ||||
|     gc.setAntialias( SWT.ON ); | ||||
|     int arc = min( width, height ) == 1 ? 1 : maxExpansion + 2; | ||||
|     gc.fillRoundRectangle( 0, 0, width, height, arc, arc ); | ||||
|   } | ||||
|  | ||||
|   private void checkDisposed() { | ||||
|     if( isDisposed() ) { | ||||
|       throw new IllegalStateException( IMAGE_DRAWER_IS_DISPOSED ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private static Color getSystemColor( int colorCode ) { | ||||
|     return getDisplay().getSystemColor( colorCode ); | ||||
|   } | ||||
|  | ||||
|   private static Color prepareColorAttribute( Color oldColor, Color newColor ) { | ||||
|     oldColor.dispose(); | ||||
|     return defensiveCopy( newColor ); | ||||
|   } | ||||
|  | ||||
|   private static Color defensiveCopy( Color background ) { | ||||
|     return new Color( getDisplay(), background.getRGB() ); | ||||
|   } | ||||
|  | ||||
|   private static Display getDisplay() { | ||||
|     return Display.getCurrent(); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,46 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import org.eclipse.swt.SWT; | ||||
| import org.eclipse.swt.graphics.Color; | ||||
| import org.eclipse.swt.graphics.Point; | ||||
| import org.eclipse.swt.widgets.Label; | ||||
|  | ||||
| class ImageUpdate { | ||||
|  | ||||
|   private final ImageDrawer imageDrawer; | ||||
|   private final Label control; | ||||
|  | ||||
|   ImageUpdate( Label control, int maxExpansion ) { | ||||
|     this.imageDrawer = new ImageDrawer( maxExpansion ); | ||||
|     this.control = control; | ||||
|     this.control.addListener( SWT.Dispose, evt -> imageDrawer.dispose() ); | ||||
|   } | ||||
|  | ||||
|   void setForeground( Color color ) { | ||||
|     imageDrawer.setForeground( color ); | ||||
|   } | ||||
|  | ||||
|   Color getForeground() { | ||||
|     return imageDrawer.getForeground(); | ||||
|   } | ||||
|  | ||||
|   void setBackground( Color color ) { | ||||
|     imageDrawer.setBackground( color ); | ||||
|   } | ||||
|  | ||||
|   Color getBackground() { | ||||
|     return imageDrawer.getBackground(); | ||||
|   } | ||||
|  | ||||
|   void update() { | ||||
|     if( !control.isDisposed() ) { | ||||
|       if( control.getImage() != null ) { | ||||
|         control.getImage().dispose(); | ||||
|       } | ||||
|       Point size = control.getSize(); | ||||
|       if( size.x > 0 && size.y > 0 ) { | ||||
|         control.setImage( imageDrawer.draw( size.x, size.y ) ); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,24 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import org.eclipse.swt.SWT; | ||||
|  | ||||
| import com.minres.scviewer.database.ui.swt.sb.ClickControl.ClickAction; | ||||
|  | ||||
| class Incrementer implements ClickAction { | ||||
|  | ||||
|   private final FlatScrollBar scrollBar; | ||||
|  | ||||
|   Incrementer( FlatScrollBar scrollBar ) { | ||||
|     this.scrollBar = scrollBar; | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void run() { | ||||
|     int selection = scrollBar.getSelection() + scrollBar.getIncrement(); | ||||
|     scrollBar.setSelectionInternal( selection, SWT.ARROW_DOWN ); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void setCoordinates( int x, int y ) { | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,37 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import org.eclipse.swt.widgets.Display; | ||||
|  | ||||
| public class MouseDownActionTimer implements Runnable { | ||||
|  | ||||
|   public static final int INITIAL_DELAY = 300; | ||||
|   public static final int FAST_DELAY = 50; | ||||
|  | ||||
|   private final ActionScheduler scheduler; | ||||
|   private final TimerAction timerAction; | ||||
|   private final ButtonClick mouseClick; | ||||
|  | ||||
|   public interface TimerAction extends Runnable { | ||||
|     boolean isEnabled(); | ||||
|   } | ||||
|  | ||||
|   public MouseDownActionTimer( TimerAction timerAction, ButtonClick mouseClick, Display display ) { | ||||
|     this.scheduler = new ActionScheduler( display, this ); | ||||
|     this.timerAction = timerAction; | ||||
|     this.mouseClick = mouseClick; | ||||
|   } | ||||
|  | ||||
|   public void activate() { | ||||
|     if( timerAction.isEnabled() ) { | ||||
|       scheduler.schedule( INITIAL_DELAY ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void run() { | ||||
|     if( mouseClick.isArmed() && timerAction.isEnabled() ) { | ||||
|       timerAction.run(); | ||||
|       scheduler.schedule( FAST_DELAY ); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,66 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import org.eclipse.swt.events.DisposeEvent; | ||||
| import org.eclipse.swt.events.DisposeListener; | ||||
| import org.eclipse.swt.events.MouseEvent; | ||||
| import org.eclipse.swt.events.MouseTrackAdapter; | ||||
| import org.eclipse.swt.graphics.Rectangle; | ||||
| import org.eclipse.swt.widgets.Display; | ||||
|  | ||||
| class MouseTracker extends MouseTrackAdapter implements Runnable, DisposeListener { | ||||
|  | ||||
|   static final int DELAY = 500; | ||||
|  | ||||
|   private final FlatScrollBar scrollBar; | ||||
|   private final int maxExpansion; | ||||
|  | ||||
|   private Rectangle expandedBounds; | ||||
|   private Rectangle originBounds; | ||||
|   private boolean mouseOver; | ||||
|   private boolean disposed; | ||||
|  | ||||
|   MouseTracker( FlatScrollBar scrollBar, int maxExpansion  ) { | ||||
|     this.scrollBar = scrollBar; | ||||
|     this.maxExpansion = maxExpansion; | ||||
|     this.scrollBar.addDisposeListener( this ); | ||||
|     this.scrollBar.up.getControl().addMouseTrackListener( this ); | ||||
|     this.scrollBar.upFast.getControl().addMouseTrackListener( this ); | ||||
|     this.scrollBar.drag.getControl().addMouseTrackListener( this ); | ||||
|     this.scrollBar.downFast.getControl().addMouseTrackListener( this ); | ||||
|     this.scrollBar.down.getControl().addMouseTrackListener( this ); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void mouseEnter( MouseEvent event ) { | ||||
|     mouseOver = true; | ||||
|     if( !disposed && originBounds == null ) { | ||||
|       originBounds = scrollBar.getBounds(); | ||||
|       scrollBar.getDirection().expand( scrollBar, maxExpansion ); | ||||
|       expandedBounds = scrollBar.getBounds(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void mouseExit( MouseEvent event ) { | ||||
|     mouseOver = false; | ||||
|     if( !disposed ) { | ||||
|       Display.getCurrent().timerExec( DELAY, this ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void run() { | ||||
|     if( !disposed && !mouseOver ) { | ||||
|       if( scrollBar.getBounds().equals( expandedBounds ) ) { | ||||
|         scrollBar.setBounds( originBounds ); | ||||
|       } | ||||
|       originBounds = null; | ||||
|       expandedBounds = null; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void widgetDisposed( DisposeEvent e ) { | ||||
|     disposed = true; | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,69 @@ | ||||
| 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.events.DisposeEvent; | ||||
| import org.eclipse.swt.events.DisposeListener; | ||||
| import org.eclipse.swt.graphics.Point; | ||||
| import org.eclipse.swt.widgets.Composite; | ||||
| import org.eclipse.swt.widgets.Event; | ||||
| import org.eclipse.swt.widgets.Listener; | ||||
|  | ||||
| public class MouseWheelShifter implements Listener, DisposeListener { | ||||
|  | ||||
|   private final FlatScrollBar scrollBar; | ||||
|   private final Composite parent; | ||||
|   private final int buttonLength; | ||||
|  | ||||
|   MouseWheelShifter( FlatScrollBar scrollBar, Composite parent, int buttonLength ) { | ||||
|     this.scrollBar = scrollBar; | ||||
|     this.parent = parent; | ||||
|     this.buttonLength = buttonLength; | ||||
|     parent.addListener( getListenerType(), this ); | ||||
|     scrollBar.addDisposeListener( this ); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void handleEvent( Event event ) { | ||||
|     handleMouseWheelScroll( event ); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void widgetDisposed( DisposeEvent e ) { | ||||
|     parent.removeListener( getListenerType(), this ); | ||||
|   } | ||||
|  | ||||
|   private void handleMouseWheelScroll( Event event ) { | ||||
|     ShiftData shiftData = newShiftData( event.count ); | ||||
|     if( shiftData.canShift() ) { | ||||
|       int selectionRange = calculateSelectionRange( scrollBar ); | ||||
|       int selectionDelta = shiftData.calculateSelectionDelta( selectionRange ); | ||||
|       int selection = scrollBar.getSelection() - selectionDelta; | ||||
|       scrollBar.setSelectionInternal( selection, scrollBar.direction.value() ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private ShiftData newShiftData( int delta ) { | ||||
|     ShiftData result; | ||||
|     if( scrollBar.direction == Direction.HORIZONTAL ) { | ||||
|       result = new ShiftData( buttonLength, getScrollBarSize().x, getDragSize().x, delta ); | ||||
|     } else { | ||||
|       result = new ShiftData( buttonLength, getScrollBarSize().y, getDragSize().y, delta ); | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   private Point getScrollBarSize() { | ||||
|     return scrollBar.getSize(); | ||||
|   } | ||||
|  | ||||
|   private Point getDragSize() { | ||||
|     return scrollBar.drag.getControl().getSize(); | ||||
|   } | ||||
|  | ||||
|   private int getListenerType() { | ||||
|     return scrollBar.direction == HORIZONTAL ? SWT.MouseHorizontalWheel: SWT.MouseVerticalWheel; | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,19 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import org.eclipse.swt.events.ControlAdapter; | ||||
| import org.eclipse.swt.events.ControlEvent; | ||||
|  | ||||
| class ResizeObserver extends ControlAdapter { | ||||
|  | ||||
|   private final FlatScrollBar flatScrollBar; | ||||
|  | ||||
|   public ResizeObserver( FlatScrollBar flatScrollBar ) { | ||||
|     this.flatScrollBar = flatScrollBar; | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void controlResized( ControlEvent event ) { | ||||
|     flatScrollBar.layout(); | ||||
|     flatScrollBar.moveAbove( null ); | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,32 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import static com.minres.scviewer.database.ui.swt.sb.ComponentDistribution.divide; | ||||
|  | ||||
| class ShiftData { | ||||
|  | ||||
|   private final int slidePixels; | ||||
|   private final int movedPixels; | ||||
|   private final int buttonLength; | ||||
|  | ||||
|   ShiftData( int buttonLength, int scrollBarPixels, int dragPixels, int movedPixels ) { | ||||
|     this.buttonLength = buttonLength; | ||||
|     this.slidePixels = calculateSlidePixels( scrollBarPixels, dragPixels ); | ||||
|     this.movedPixels = movedPixels; | ||||
|   } | ||||
|  | ||||
|   boolean canShift( ) { | ||||
|     return slidePixels > 0; | ||||
|   } | ||||
|  | ||||
|   int calculateSelectionDelta( int selectionRange ) { | ||||
|     return divide( movedPixels * selectionRange, slidePixels ); | ||||
|   } | ||||
|  | ||||
|   static int calculateSelectionRange( FlatScrollBar scrollBar ) { | ||||
|     return scrollBar.getMaximum() - scrollBar.getMinimum() - scrollBar.getThumb(); | ||||
|   } | ||||
|  | ||||
|   private int calculateSlidePixels( int scrollBarPixels, int dragPixels ) { | ||||
|     return scrollBarPixels - 2 * buttonLength - dragPixels; | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,43 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import java.util.Collection; | ||||
|  | ||||
| import org.eclipse.swt.events.SelectionAdapter; | ||||
| import org.eclipse.swt.events.SelectionEvent; | ||||
| import org.eclipse.swt.events.SelectionListener; | ||||
| import org.eclipse.swt.widgets.Event; | ||||
| import org.eclipse.swt.widgets.Listener; | ||||
|  | ||||
| class UntypedSelectionAdapter extends SelectionAdapter { | ||||
|  | ||||
|   final Listener listener; | ||||
|  | ||||
|   UntypedSelectionAdapter( Listener listener ) { | ||||
|     this.listener = listener; | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void widgetSelected( SelectionEvent selectionEvent ) { | ||||
|     Event event = new Event(); | ||||
|     event.widget = selectionEvent.widget; | ||||
|     event.detail = selectionEvent.detail; | ||||
|     listener.handleEvent( event ); | ||||
|   } | ||||
|  | ||||
|   static SelectionListener lookup( Collection<SelectionListener> listeners, Listener untypedListener ) { | ||||
|     for( SelectionListener listener : listeners ) { | ||||
|       if( isAdapterType( listener ) && matches( untypedListener, listener ) ) { | ||||
|         return listener; | ||||
|       } | ||||
|     } | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   private static boolean isAdapterType( SelectionListener listener ) { | ||||
|     return listener instanceof UntypedSelectionAdapter; | ||||
|   } | ||||
|  | ||||
|   private static boolean matches( Listener untypedListener, SelectionListener listener ) { | ||||
|     return ( ( UntypedSelectionAdapter )listener ).listener == untypedListener; | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,7 @@ | ||||
| package com.minres.scviewer.database.ui.swt.sb; | ||||
|  | ||||
| import org.eclipse.swt.widgets.Control; | ||||
|  | ||||
| public interface ViewComponent { | ||||
|   Control getControl(); | ||||
| } | ||||
| @@ -29,17 +29,14 @@ import org.eclipse.swt.graphics.Rectangle; | ||||
| import org.eclipse.swt.widgets.Display; | ||||
|  | ||||
| /** | ||||
|  * Utility class for managing OS resources associated with SWT controls such as | ||||
|  * colors, fonts, images, etc. | ||||
|  * Utility class for managing OS resources associated with SWT controls such as colors, fonts, images, etc. | ||||
|  * <p> | ||||
|  * !!! IMPORTANT !!! Application code must explicitly invoke the | ||||
|  * <code>dispose()</code> method to release the operating system resources | ||||
|  * managed by cached objects when those objects and OS resources are no longer | ||||
|  * !!! IMPORTANT !!! Application code must explicitly invoke the <code>dispose()</code> method to release the | ||||
|  * operating system resources managed by cached objects when those objects and OS resources are no longer | ||||
|  * needed (e.g. on application shutdown) | ||||
|  * <p> | ||||
|  * This class may be freely distributed as part of any application or plugin. | ||||
|  * <p> | ||||
|  *  | ||||
|  * @author scheglov_ke | ||||
|  * @author Dan Rubel | ||||
|  */ | ||||
| @@ -49,54 +46,57 @@ public class SWTResourceManager { | ||||
| 	// Color | ||||
| 	// | ||||
| 	//////////////////////////////////////////////////////////////////////////// | ||||
| 	private static Map<RGB, Color> colorMap = new HashMap<>(); | ||||
|  | ||||
| 	private SWTResourceManager() {} | ||||
| 	 | ||||
| 	private static Map<RGB, Color> m_colorMap = new HashMap<RGB, Color>(); | ||||
| 	/** | ||||
| 	 * Returns the system {@link Color} matching the specific ID. | ||||
| 	 *  | ||||
| 	 * @param systemColorID the ID value for the color | ||||
| 	 * @param systemColorID | ||||
| 	 *            the ID value for the color | ||||
| 	 * @return the system {@link Color} matching the specific ID | ||||
| 	 */ | ||||
| 	public static Color getColor(int systemColorID) { | ||||
| 		Display display = Display.getCurrent(); | ||||
| 		return display.getSystemColor(systemColorID); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a {@link Color} given its red, green and blue component values. | ||||
| 	 *  | ||||
| 	 * @param r the red component of the color | ||||
| 	 * @param g the green component of the color | ||||
| 	 * @param b the blue component of the color | ||||
| 	 * @return the {@link Color} matching the given red, green and blue component | ||||
| 	 *         values | ||||
| 	 * @param r | ||||
| 	 *            the red component of the color | ||||
| 	 * @param g | ||||
| 	 *            the green component of the color | ||||
| 	 * @param b | ||||
| 	 *            the blue component of the color | ||||
| 	 * @return the {@link Color} matching the given red, green and blue component values | ||||
| 	 */ | ||||
| 	public static Color getColor(int r, int g, int b) { | ||||
| 		return getColor(new RGB(r, g, b)); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a {@link Color} given its RGB value. | ||||
| 	 *  | ||||
| 	 * @param rgb the {@link RGB} value of the color | ||||
| 	 * @param rgb | ||||
| 	 *            the {@link RGB} value of the color | ||||
| 	 * @return the {@link Color} matching the RGB value | ||||
| 	 */ | ||||
| 	public static Color getColor(RGB rgb) { | ||||
| 		return colorMap.computeIfAbsent(rgb, k -> new Color(Display.getCurrent(), rgb)); | ||||
| 		Color color = m_colorMap.get(rgb); | ||||
| 		if (color == null) { | ||||
| 			Display display = Display.getCurrent(); | ||||
| 			color = new Color(display, rgb); | ||||
| 			m_colorMap.put(rgb, color); | ||||
| 		} | ||||
| 		return color; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Dispose of all the cached {@link Color}'s. | ||||
| 	 */ | ||||
| 	public static void disposeColors() { | ||||
| 		for (Color color : colorMap.values()) { | ||||
| 		for (Color color : m_colorMap.values()) { | ||||
| 			color.dispose(); | ||||
| 		} | ||||
| 		colorMap.clear(); | ||||
| 		m_colorMap.clear(); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////// | ||||
| 	// | ||||
| 	// Image | ||||
| @@ -105,12 +105,12 @@ public class SWTResourceManager { | ||||
| 	/** | ||||
| 	 * Maps image paths to images. | ||||
| 	 */ | ||||
| 	private static Map<String, Image> imageMap = new HashMap<>(); | ||||
|  | ||||
| 	private static Map<String, Image> m_imageMap = new HashMap<String, Image>(); | ||||
| 	/** | ||||
| 	 * Returns an {@link Image} encoded by the specified {@link InputStream}. | ||||
| 	 *  | ||||
| 	 * @param stream the {@link InputStream} encoding the image data | ||||
| 	 * @param stream | ||||
| 	 *            the {@link InputStream} encoding the image data | ||||
| 	 * @return the {@link Image} encoded by the specified input stream | ||||
| 	 */ | ||||
| 	protected static Image getImage(InputStream stream) throws IOException { | ||||
| @@ -125,55 +125,52 @@ public class SWTResourceManager { | ||||
| 			stream.close(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns an {@link Image} stored in the file at the specified path. | ||||
| 	 *  | ||||
| 	 * @param path the path to the image file | ||||
| 	 * @param path | ||||
| 	 *            the path to the image file | ||||
| 	 * @return the {@link Image} stored in the file at the specified path | ||||
| 	 */ | ||||
| 	public static Image getImage(String path) { | ||||
| 		Image image = imageMap.get(path); | ||||
| 		Image image = m_imageMap.get(path); | ||||
| 		if (image == null) { | ||||
| 			try { | ||||
| 				image = getImage(new FileInputStream(path)); | ||||
| 				imageMap.put(path, image); | ||||
| 				m_imageMap.put(path, image); | ||||
| 			} catch (Exception e) { | ||||
| 				image = getMissingImage(); | ||||
| 				imageMap.put(path, image); | ||||
| 				m_imageMap.put(path, image); | ||||
| 			} | ||||
| 		} | ||||
| 		return image; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns an {@link Image} stored in the file at the specified path relative to | ||||
| 	 * the specified class. | ||||
| 	 * Returns an {@link Image} stored in the file at the specified path relative to the specified class. | ||||
| 	 *  | ||||
| 	 * @param clazz the {@link Class} relative to which to find the image | ||||
| 	 * @param path  the path to the image file, if starts with <code>'/'</code> | ||||
| 	 * @param clazz | ||||
| 	 *            the {@link Class} relative to which to find the image | ||||
| 	 * @param path | ||||
| 	 *            the path to the image file, if starts with <code>'/'</code> | ||||
| 	 * @return the {@link Image} stored in the file at the specified path | ||||
| 	 */ | ||||
| 	public static Image getImage(Class<?> clazz, String path) { | ||||
| 		String key = clazz.getName() + '|' + path; | ||||
| 		Image image = imageMap.get(key); | ||||
| 		Image image = m_imageMap.get(key); | ||||
| 		if (image == null) { | ||||
| 			try { | ||||
| 				image = getImage(clazz.getResourceAsStream(path)); | ||||
| 				imageMap.put(key, image); | ||||
| 				m_imageMap.put(key, image); | ||||
| 			} catch (Exception e) { | ||||
| 				image = getMissingImage(); | ||||
| 				imageMap.put(key, image); | ||||
| 				m_imageMap.put(key, image); | ||||
| 			} | ||||
| 		} | ||||
| 		return image; | ||||
| 	} | ||||
|  | ||||
| 	private static final int MISSING_IMAGE_SIZE = 10; | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the small {@link Image} that can be used as placeholder for missing | ||||
| 	 *         image. | ||||
| 	 * @return the small {@link Image} that can be used as placeholder for missing image. | ||||
| 	 */ | ||||
| 	private static Image getMissingImage() { | ||||
| 		Image image = new Image(Display.getCurrent(), MISSING_IMAGE_SIZE, MISSING_IMAGE_SIZE); | ||||
| @@ -185,7 +182,6 @@ public class SWTResourceManager { | ||||
| 		// | ||||
| 		return image; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Style constant for placing decorator image in top left corner of base image. | ||||
| 	 */ | ||||
| @@ -195,13 +191,11 @@ public class SWTResourceManager { | ||||
| 	 */ | ||||
| 	public static final int TOP_RIGHT = 2; | ||||
| 	/** | ||||
| 	 * Style constant for placing decorator image in bottom left corner of base | ||||
| 	 * image. | ||||
| 	 * Style constant for placing decorator image in bottom left corner of base image. | ||||
| 	 */ | ||||
| 	public static final int BOTTOM_LEFT = 3; | ||||
| 	/** | ||||
| 	 * Style constant for placing decorator image in bottom right corner of base | ||||
| 	 * image. | ||||
| 	 * Style constant for placing decorator image in bottom right corner of base image. | ||||
| 	 */ | ||||
| 	public static final int BOTTOM_RIGHT = 4; | ||||
| 	/** | ||||
| @@ -212,77 +206,83 @@ public class SWTResourceManager { | ||||
| 	 * Maps images to decorated images. | ||||
| 	 */ | ||||
| 	@SuppressWarnings("unchecked") | ||||
| 	private static Map<Image, Map<Image, Image>>[] decoratedImageMap = new Map[LAST_CORNER_KEY]; | ||||
|  | ||||
| 	private static Map<Image, Map<Image, Image>>[] m_decoratedImageMap = new Map[LAST_CORNER_KEY]; | ||||
| 	/** | ||||
| 	 * Returns an {@link Image} composed of a base image decorated by another image. | ||||
| 	 *  | ||||
| 	 * @param baseImage the base {@link Image} that should be decorated | ||||
| 	 * @param decorator the {@link Image} to decorate the base image | ||||
| 	 * @param baseImage | ||||
| 	 *            the base {@link Image} that should be decorated | ||||
| 	 * @param decorator | ||||
| 	 *            the {@link Image} to decorate the base image | ||||
| 	 * @return {@link Image} The resulting decorated image | ||||
| 	 */ | ||||
| 	public static Image decorateImage(Image baseImage, Image decorator) { | ||||
| 		return decorateImage(baseImage, decorator, BOTTOM_RIGHT); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns an {@link Image} composed of a base image decorated by another image. | ||||
| 	 *  | ||||
| 	 * @param baseImage the base {@link Image} that should be decorated | ||||
| 	 * @param decorator the {@link Image} to decorate the base image | ||||
| 	 * @param corner    the corner to place decorator image | ||||
| 	 * @param baseImage | ||||
| 	 *            the base {@link Image} that should be decorated | ||||
| 	 * @param decorator | ||||
| 	 *            the {@link Image} to decorate the base image | ||||
| 	 * @param corner | ||||
| 	 *            the corner to place decorator image | ||||
| 	 * @return the resulting decorated {@link Image} | ||||
| 	 */ | ||||
| 	public static Image decorateImage(final Image baseImage, final Image decorator, final int corner) { | ||||
| 		if (corner <= 0 || corner >= LAST_CORNER_KEY) { | ||||
| 			throw new IllegalArgumentException("Wrong decorate corner"); | ||||
| 		} | ||||
| 		Map<Image, Map<Image, Image>> cornerDecoratedImageMap = decoratedImageMap[corner]; | ||||
| 		Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[corner]; | ||||
| 		if (cornerDecoratedImageMap == null) { | ||||
| 			cornerDecoratedImageMap = new HashMap<>(); | ||||
| 			decoratedImageMap[corner] = cornerDecoratedImageMap; | ||||
| 			cornerDecoratedImageMap = new HashMap<Image, Map<Image, Image>>(); | ||||
| 			m_decoratedImageMap[corner] = cornerDecoratedImageMap; | ||||
| 		} | ||||
| 		Map<Image, Image> decoratedMap = cornerDecoratedImageMap.computeIfAbsent(baseImage, | ||||
| 				k -> new HashMap<Image, Image>()); | ||||
| 		return decoratedMap.computeIfAbsent(decorator, k -> { | ||||
| 		Map<Image, Image> decoratedMap = cornerDecoratedImageMap.get(baseImage); | ||||
| 		if (decoratedMap == null) { | ||||
| 			decoratedMap = new HashMap<Image, Image>(); | ||||
| 			cornerDecoratedImageMap.put(baseImage, decoratedMap); | ||||
| 		} | ||||
| 		// | ||||
| 		Image result = decoratedMap.get(decorator); | ||||
| 		if (result == null) { | ||||
| 			Rectangle bib = baseImage.getBounds(); | ||||
| 			Rectangle dib = decorator.getBounds(); | ||||
| 			Image result = new Image(Display.getCurrent(), bib.width, bib.height); | ||||
| 			// | ||||
| 			result = new Image(Display.getCurrent(), bib.width, bib.height); | ||||
| 			// | ||||
| 			GC gc = new GC(result); | ||||
| 			gc.drawImage(baseImage, 0, 0); | ||||
| 			switch (corner) { | ||||
| 			case TOP_LEFT: | ||||
| 			if (corner == TOP_LEFT) { | ||||
| 				gc.drawImage(decorator, 0, 0); | ||||
| 				break; | ||||
| 			case TOP_RIGHT: | ||||
| 			} else if (corner == TOP_RIGHT) { | ||||
| 				gc.drawImage(decorator, bib.width - dib.width, 0); | ||||
| 				break; | ||||
| 			case BOTTOM_LEFT: | ||||
| 			} else if (corner == BOTTOM_LEFT) { | ||||
| 				gc.drawImage(decorator, 0, bib.height - dib.height); | ||||
| 				break; | ||||
| 			case BOTTOM_RIGHT: | ||||
| 			} else if (corner == BOTTOM_RIGHT) { | ||||
| 				gc.drawImage(decorator, bib.width - dib.width, bib.height - dib.height); | ||||
| 				break; | ||||
| 			default: | ||||
| 				// do nothing | ||||
| 			} | ||||
| 			gc.dispose(); | ||||
| 			return result; | ||||
| 		}); | ||||
| 			// | ||||
| 			decoratedMap.put(decorator, result); | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Dispose all of the cached {@link Image}'s. | ||||
| 	 */ | ||||
| 	public static void disposeImages() { | ||||
| 		// dispose loaded images | ||||
| 		for (Image image : imageMap.values()) { | ||||
| 			image.dispose(); | ||||
| 		{ | ||||
| 			for (Image image : m_imageMap.values()) { | ||||
| 				image.dispose(); | ||||
| 			} | ||||
| 			m_imageMap.clear(); | ||||
| 		} | ||||
| 		imageMap.clear(); | ||||
| 		// dispose decorated images | ||||
| 		for (int i = 0; i < decoratedImageMap.length; i++) { | ||||
| 			Map<Image, Map<Image, Image>> cornerDecoratedImageMap = decoratedImageMap[i]; | ||||
| 		for (int i = 0; i < m_decoratedImageMap.length; i++) { | ||||
| 			Map<Image, Map<Image, Image>> cornerDecoratedImageMap = m_decoratedImageMap[i]; | ||||
| 			if (cornerDecoratedImageMap != null) { | ||||
| 				for (Map<Image, Image> decoratedMap : cornerDecoratedImageMap.values()) { | ||||
| 					for (Image image : decoratedMap.values()) { | ||||
| @@ -294,7 +294,6 @@ public class SWTResourceManager { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////// | ||||
| 	// | ||||
| 	// Font | ||||
| @@ -303,39 +302,45 @@ public class SWTResourceManager { | ||||
| 	/** | ||||
| 	 * Maps font names to fonts. | ||||
| 	 */ | ||||
| 	private static Map<String, Font> fontMap = new HashMap<>(); | ||||
| 	private static Map<String, Font> m_fontMap = new HashMap<String, Font>(); | ||||
| 	/** | ||||
| 	 * Maps fonts to their bold versions. | ||||
| 	 */ | ||||
| 	private static Map<Font, Font> fontToBoldFontMap = new HashMap<>(); | ||||
|  | ||||
| 	private static Map<Font, Font> m_fontToBoldFontMap = new HashMap<Font, Font>(); | ||||
| 	/** | ||||
| 	 * Returns a {@link Font} based on its name, height and style. | ||||
| 	 *  | ||||
| 	 * @param name   the name of the font | ||||
| 	 * @param height the height of the font | ||||
| 	 * @param style  the style of the font | ||||
| 	 * @param name | ||||
| 	 *            the name of the font | ||||
| 	 * @param height | ||||
| 	 *            the height of the font | ||||
| 	 * @param style | ||||
| 	 *            the style of the font | ||||
| 	 * @return {@link Font} The font matching the name, height and style | ||||
| 	 */ | ||||
| 	public static Font getFont(String name, int height, int style) { | ||||
| 		return getFont(name, height, style, false, false); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a {@link Font} based on its name, height and style. Windows-specific | ||||
| 	 * strikeout and underline flags are also supported. | ||||
| 	 * Returns a {@link Font} based on its name, height and style. Windows-specific strikeout and underline | ||||
| 	 * flags are also supported. | ||||
| 	 *  | ||||
| 	 * @param name      the name of the font | ||||
| 	 * @param size      the size of the font | ||||
| 	 * @param style     the style of the font | ||||
| 	 * @param strikeout the strikeout flag (warning: Windows only) | ||||
| 	 * @param underline the underline flag (warning: Windows only) | ||||
| 	 * @return {@link Font} The font matching the name, height, style, strikeout and | ||||
| 	 *         underline | ||||
| 	 * @param name | ||||
| 	 *            the name of the font | ||||
| 	 * @param size | ||||
| 	 *            the size of the font | ||||
| 	 * @param style | ||||
| 	 *            the style of the font | ||||
| 	 * @param strikeout | ||||
| 	 *            the strikeout flag (warning: Windows only) | ||||
| 	 * @param underline | ||||
| 	 *            the underline flag (warning: Windows only) | ||||
| 	 * @return {@link Font} The font matching the name, height, style, strikeout and underline | ||||
| 	 */ | ||||
| 	public static Font getFont(String name, int size, int style, boolean strikeout, boolean underline) { | ||||
| 		String fontName = name + '|' + size + '|' + style + '|' + strikeout + '|' + underline; | ||||
| 		return fontMap.computeIfAbsent(fontName, k -> { | ||||
| 		Font font = m_fontMap.get(fontName); | ||||
| 		if (font == null) { | ||||
| 			FontData fontData = new FontData(name, size, style); | ||||
| 			if (strikeout || underline) { | ||||
| 				try { | ||||
| @@ -349,45 +354,47 @@ public class SWTResourceManager { | ||||
| 							logFontClass.getField("lfUnderline").set(logFont, Byte.valueOf((byte) 1)); //$NON-NLS-1$ | ||||
| 						} | ||||
| 					} | ||||
| 				} catch (Exception e) { | ||||
| 				} catch (Throwable e) { | ||||
| 					System.err.println("Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); //$NON-NLS-1$ //$NON-NLS-2$ | ||||
| 				} | ||||
| 			} | ||||
| 			return new Font(Display.getCurrent(), fontData); | ||||
|  | ||||
| 		}); | ||||
|  | ||||
| 			font = new Font(Display.getCurrent(), fontData); | ||||
| 			m_fontMap.put(fontName, font); | ||||
| 		} | ||||
| 		return font; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a bold version of the given {@link Font}. | ||||
| 	 *  | ||||
| 	 * @param baseFont the {@link Font} for which a bold version is desired | ||||
| 	 * @param baseFont | ||||
| 	 *            the {@link Font} for which a bold version is desired | ||||
| 	 * @return the bold version of the given {@link Font} | ||||
| 	 */ | ||||
| 	public static Font getBoldFont(Font baseFont) { | ||||
| 		return fontToBoldFontMap.computeIfAbsent(baseFont, k -> { | ||||
| 			FontData[] fontDatas = baseFont.getFontData(); | ||||
| 		Font font = m_fontToBoldFontMap.get(baseFont); | ||||
| 		if (font == null) { | ||||
| 			FontData fontDatas[] = baseFont.getFontData(); | ||||
| 			FontData data = fontDatas[0]; | ||||
| 			return new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD); | ||||
| 		}); | ||||
| 			font = new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD); | ||||
| 			m_fontToBoldFontMap.put(baseFont, font); | ||||
| 		} | ||||
| 		return font; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Dispose all of the cached {@link Font}'s. | ||||
| 	 */ | ||||
| 	public static void disposeFonts() { | ||||
| 		// clear fonts | ||||
| 		for (Font font : fontMap.values()) { | ||||
| 		for (Font font : m_fontMap.values()) { | ||||
| 			font.dispose(); | ||||
| 		} | ||||
| 		fontMap.clear(); | ||||
| 		m_fontMap.clear(); | ||||
| 		// clear bold fonts | ||||
| 		for (Font font : fontToBoldFontMap.values()) { | ||||
| 		for (Font font : m_fontToBoldFontMap.values()) { | ||||
| 			font.dispose(); | ||||
| 		} | ||||
| 		fontToBoldFontMap.clear(); | ||||
| 		m_fontToBoldFontMap.clear(); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////// | ||||
| 	// | ||||
| 	// Cursor | ||||
| @@ -396,38 +403,40 @@ public class SWTResourceManager { | ||||
| 	/** | ||||
| 	 * Maps IDs to cursors. | ||||
| 	 */ | ||||
| 	private static Map<Integer, Cursor> idToCursorMap = new HashMap<>(); | ||||
|  | ||||
| 	private static Map<Integer, Cursor> m_idToCursorMap = new HashMap<Integer, Cursor>(); | ||||
| 	/** | ||||
| 	 * Returns the system cursor matching the specific ID. | ||||
| 	 *  | ||||
| 	 * @param id int The ID value for the cursor | ||||
| 	 * @param id | ||||
| 	 *            int The ID value for the cursor | ||||
| 	 * @return Cursor The system cursor matching the specific ID | ||||
| 	 */ | ||||
| 	public static Cursor getCursor(int id) { | ||||
| 		Integer key = Integer.valueOf(id); | ||||
| 		return idToCursorMap.computeIfAbsent(key, k -> new Cursor(Display.getDefault(), id)); | ||||
| 		Cursor cursor = m_idToCursorMap.get(key); | ||||
| 		if (cursor == null) { | ||||
| 			cursor = new Cursor(Display.getDefault(), id); | ||||
| 			m_idToCursorMap.put(key, cursor); | ||||
| 		} | ||||
| 		return cursor; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Dispose all of the cached cursors. | ||||
| 	 */ | ||||
| 	public static void disposeCursors() { | ||||
| 		for (Cursor cursor : idToCursorMap.values()) { | ||||
| 		for (Cursor cursor : m_idToCursorMap.values()) { | ||||
| 			cursor.dispose(); | ||||
| 		} | ||||
| 		idToCursorMap.clear(); | ||||
| 		m_idToCursorMap.clear(); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////// | ||||
| 	// | ||||
| 	// General | ||||
| 	// | ||||
| 	//////////////////////////////////////////////////////////////////////////// | ||||
| 	/** | ||||
| 	 * Dispose of cached objects and their underlying OS resources. This should only | ||||
| 	 * be called when the cached objects are no longer needed (e.g. on application | ||||
| 	 * shutdown). | ||||
| 	 * Dispose of cached objects and their underlying OS resources. This should only be called when the cached | ||||
| 	 * objects are no longer needed (e.g. on application shutdown). | ||||
| 	 */ | ||||
| 	public static void dispose() { | ||||
| 		disposeColors(); | ||||
|   | ||||
| @@ -5,8 +5,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <packaging>eclipse-plugin</packaging> | ||||
| </project> | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <packaging>eclipse-plugin</packaging> | ||||
|   <version>4.0.0-SNAPSHOT</version> | ||||
|   | ||||
| @@ -12,18 +12,19 @@ | ||||
|     <children xsi:type="basic:Part" xmi:id="_hXh-kEYFEeyPM8G0E2EYww" elementId="com.minres.scviewer.e4.application.dialog.onlinehelp" toBeRendered="false" visible="false" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.HelpDialog" label="SCViewer Online Help" bindingContexts="_95Pfu3NmEeWBq8z1Dv39LA" closeable="true"/> | ||||
|     <mainMenu xmi:id="_95PfyXNmEeWBq8z1Dv39LA" elementId="menu:org.eclipse.ui.main.menu"> | ||||
|       <children xsi:type="menu:Menu" xmi:id="_95QGwHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.menu.file" label="File"> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_igsK0BkREeudD5MqrWoETQ" elementId="" label="Open Database" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/folder_database.png" mnemonics="M1+O" command="_95PfwHNmEeWBq8z1Dv39LA"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_VJG3YHgvEeWwZ-9vrAR2UQ" elementId="" label="Re-load Database" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/database_refresh.png" mnemonics="M1+R" command="_srACsBkREeudD5MqrWoETQ"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_igsK0BkREeudD5MqrWoETQ" elementId="" label="Open Database" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/folder_database.png" mnemonics="" command="_95PfwHNmEeWBq8z1Dv39LA"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_VJG3YHgvEeWwZ-9vrAR2UQ" elementId="" label="Re-load Database" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/database_refresh.png" mnemonics="" command="_srACsBkREeudD5MqrWoETQ"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_e7MOYJedEeW09eyIbHsdvg" elementId="" label="Load active tab settings" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/folder_page.png" command="_7-AIMJebEeW09eyIbHsdvg"> | ||||
|           <parameters xmi:id="_4vtYgJehEeW09eyIbHsdvg" elementId="com.minres.scviewer.e4.application.parameter.30" name="com.minres.scviewer.e4.application.commandparameter.loadStore" value="load"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_95QGwnNmEeWBq8z1Dv39LA" label="Save active tab settings" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/script_save.png" command="_7-AIMJebEeW09eyIbHsdvg"> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_95QGwnNmEeWBq8z1Dv39LA" label="Save active tab settings" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/script_save.png" mnemonics="" command="_7-AIMJebEeW09eyIbHsdvg"> | ||||
|           <parameters xmi:id="_61QIsJehEeW09eyIbHsdvg" elementId="com.minres.scviewer.e4.application.parameter.31" name="com.minres.scviewer.e4.application.commandparameter.loadStore" value="store"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_95QGw3NmEeWBq8z1Dv39LA" label="Quit" command="_95PfvHNmEeWBq8z1Dv39LA"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:Menu" xmi:id="_ZyHC0HgvEeWwZ-9vrAR2UQ" elementId="" label="Edit"> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_cPlx4HgvEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledmenuitem.delete" label="Delete" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/cross.png" command="_WUZ2wHXHEeWwZ-9vrAR2UQ"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_FiwZcEhdEeyp3vLifEzGbQ" elementId="com.minres.scviewer.e4.application.handledmenuitem.delete" label="Delete" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/cross.png" command="_WUZ2wHXHEeWwZ-9vrAR2UQ"/> | ||||
|         <children xsi:type="menu:HandledMenuItem" xmi:id="_cPlx4HgvEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledmenuitem.delete" label="Select All" iconURI="" command="_bV-TMHXHEeWwZ-9vrAR2UQ"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:Menu" xmi:id="_XmZY4HchEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.menu.navigate" label="Navigate"> | ||||
|         <children xsi:type="menu:Menu" xmi:id="_VCn_cHgwEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.menu.waveform" label="Waveform ..."> | ||||
| @@ -80,41 +81,6 @@ | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_FrGmEHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.movestreamdown" label="Move Stream down" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/down_blue.png" tooltip="Move stream/waveform in list down" command="_N_sOkHXHEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_VA_yAHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.9" name="com.minres.scviewer.e4.application.command.movewaveformupCommand.parameter.dir" value="down"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:ToolBarSeparator" xmi:id="_srcD0HgwEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbarseparator.3"/> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_GKi7IHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.previousevent" label="Previous Event" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/reverse_blue.png" tooltip="Navigate to previous event in stream/waveform" command="_79rx4HabEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_XS7YYHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.10" name="com.minres.scviewer.e4.application.command.navigateEventCommand.parameter.dir" value="prev"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_GjlGMHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.nextevent" label="Next Event" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/play_blue.png" tooltip="Navigate to next event in stream/waveform" command="_79rx4HabEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_ZzTqcHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.11" name="com.minres.scviewer.e4.application.command.navigateEventCommand.parameter.dir" value="next"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:ToolBarSeparator" xmi:id="_tcxaIHgwEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbarseparator.4"/> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_HdKZkHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.previoustransaction" label="Previous Transaction" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/reverse_green.png" tooltip="Navigate to previous transaction" command="_Gn3lEHXKEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_cuGAkHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.12" name="com.minres.scviewer.e4.application.command.navigateTransCommand.parameter.dir" value="prev"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:ToolControl" xmi:id="_LtQhcIuKEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.toolcontrol.0" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.elements.RelationTypeToolControl"/> | ||||
|         <children xsi:type="menu:DirectToolItem" xmi:id="_Z7ZQkIuJEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.directtoolitem.nextprevinstream" toBeRendered="false" visible="false" label="Next/Prev in stream"> | ||||
|           <menu xmi:id="_aPyMMIuJEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.menu.2"> | ||||
|             <children xsi:type="menu:DynamicMenuContribution" xmi:id="_cnNWkIuJEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.dynamicmenucontribution.2" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.NavigateContribution"/> | ||||
|           </menu> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_H7bp8HcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.nexttransaction" label="Next Transaction" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/play_green.png" tooltip="Navigate to next transaction" command="_Gn3lEHXKEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_fiO8IHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.13" name="com.minres.scviewer.e4.application.command.navigateTransCommand.parameter.dir" value="next"/> | ||||
|         </children> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBar" xmi:id="_oQdMUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbar.1"> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_LFGfsEZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfull" label="Zoom full" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_full.png" tooltip="Zoom full range" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_LFGfsUZEEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.parameter.full" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="full"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_5DrGQHf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom fit" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_fit.png" tooltip="Zoom between cursor and marker" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_5DrGQXf4EeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.fit" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:ToolBarSeparator" xmi:id="_p1AvUHcqEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbarseparator.1"/> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_XMQPAHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomin" label="Zoom in" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier_zoom_in.png" tooltip="Zoom in by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_fi5w4HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.in" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/> | ||||
|         </children> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_XqTc8HcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomout" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magifier_zoom_out.png" tooltip="Zoom out by a factor of 3" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|           <parameters xmi:id="_d7OBYHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.out" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/> | ||||
|         </children> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBar" xmi:id="_fwn8wGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.toolbar.2"> | ||||
|         <children xsi:type="menu:HandledToolItem" xmi:id="_j-XIgGtTEeqmlpoaaMHoiw" elementId="com.minres.scviewer.e4.application.handledtoolitem.txdetails" label="TX Details" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/application_side_expand.png" tooltip="Show tx details parts" selected="true" type="Check" command="_Fj1gQEYoEeyKK_icsY7Xjg"> | ||||
| @@ -134,9 +100,6 @@ | ||||
|       </children> | ||||
|     </trimBars> | ||||
|   </children> | ||||
|   <children xsi:type="basic:Window" xmi:id="_Gm0qAEamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.window.help" toBeRendered="false" selectedElement="_M5eT0EamEeyPDuc8x6Ggxw" label="SC Viewer Help" width="800" height="600"> | ||||
|     <children xsi:type="basic:Part" xmi:id="_M5eT0EamEeyPDuc8x6Ggxw" elementId="com.minres.scviewer.e4.application.part.container" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.help.HelpBrowser"/> | ||||
|   </children> | ||||
|   <handlers xmi:id="_95PfvXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.quitCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.QuitHandler" command="_95PfvHNmEeWBq8z1Dv39LA"/> | ||||
|   <handlers xmi:id="_95PfwXNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.openCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.OpenHandler" command="_95PfwHNmEeWBq8z1Dv39LA"/> | ||||
|   <handlers xmi:id="_95PfxHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.handler.saveCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SaveHandler" command="_95Pfw3NmEeWBq8z1Dv39LA"/> | ||||
| @@ -156,16 +119,7 @@ | ||||
|     <bindings xmi:id="_95Pfv3NmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.keybinding.quit" keySequence="M1+Q" command="_95PfvHNmEeWBq8z1Dv39LA"> | ||||
|       <tags>type:user</tags> | ||||
|     </bindings> | ||||
|   </bindingTables> | ||||
|   <bindingTables xmi:id="_zZFy0GVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.bindingtable.waveform" bindingContext="_q4VSsGVNEeqSQM-A6dw9ig"> | ||||
|     <bindings xmi:id="_1o3dEGVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.keybinding.zoom_in" keySequence="M1++" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|       <tags>type:user</tags> | ||||
|       <parameters xmi:id="_53UagGVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.parameter.33" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/> | ||||
|     </bindings> | ||||
|     <bindings xmi:id="_8i3awGVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.keybinding.zoom_out" keySequence="M1+-" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|       <tags>type:user</tags> | ||||
|       <parameters xmi:id="__UCh4GVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.parameter.34" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/> | ||||
|     </bindings> | ||||
|     <bindings xmi:id="_2-008EhnEeyp3vLifEzGbQ" elementId="com.minres.scviewer.e4.application.keybinding.help" keySequence="F1" command="_lqjIYEYEEeyPM8G0E2EYww"/> | ||||
|   </bindingTables> | ||||
|   <bindingTables xmi:id="_XullMGVOEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.bindingtable.window" bindingContext="_95PfunNmEeWBq8z1Dv39LA"> | ||||
|     <bindings xmi:id="_95PfwnNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.keybinding.load" keySequence="M1+L" command="_7-AIMJebEeW09eyIbHsdvg"> | ||||
| @@ -182,20 +136,22 @@ | ||||
|     <bindings xmi:id="_3PRIQGVPEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.keybinding.open" keySequence="M1+O" command="_95PfwHNmEeWBq8z1Dv39LA"> | ||||
|       <tags>type:user</tags> | ||||
|     </bindings> | ||||
|   </bindingTables> | ||||
|   <bindingTables xmi:id="_mnMrUGVmEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.bindingtable.0" bindingContext="_iQ3kQGVmEeqSQM-A6dw9ig"> | ||||
|     <bindings xmi:id="_n9yDwGVmEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.keybinding.0" keySequence="M1+A" command="_bV-TMHXHEeWwZ-9vrAR2UQ"> | ||||
|     <bindings xmi:id="_QcOn8EheEeyp3vLifEzGbQ" elementId="com.minres.scviewer.e4.application.keybinding.1" keySequence="M1+A" command="_bV-TMHXHEeWwZ-9vrAR2UQ"/> | ||||
|     <bindings xmi:id="_1o3dEGVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.keybinding.zoom_in" keySequence="M1++" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|       <tags>type:user</tags> | ||||
|       <parameters xmi:id="_53UagGVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.parameter.33" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/> | ||||
|     </bindings> | ||||
|     <bindings xmi:id="_8i3awGVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.keybinding.zoom_out" keySequence="M1+-" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|       <tags>type:user</tags> | ||||
|       <parameters xmi:id="__UCh4GVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.parameter.34" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/> | ||||
|     </bindings> | ||||
|     <bindings xmi:id="_KjmnsEheEeyp3vLifEzGbQ" elementId="com.minres.scviewer.e4.application.keybinding.0" keySequence="M1+R" command="_srACsBkREeudD5MqrWoETQ"/> | ||||
|   </bindingTables> | ||||
|   <rootContext xmi:id="_95PfuXNmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.contexts.dialogAndWindow" name="In Dialog and Windows"> | ||||
|     <children xmi:id="_95PfunNmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.contexts.window" name="In Windows"> | ||||
|       <children xmi:id="_q4VSsGVNEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.bindingcontext.waveform" name="In Waveform Part"/> | ||||
|       <children xmi:id="_iQ3kQGVmEeqSQM-A6dw9ig" elementId="com.minres.scviewer.e4.application.bindingcontext.indesignbrowser" name="In DesignBrowser"/> | ||||
|     </children> | ||||
|     <children xmi:id="_95PfunNmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.contexts.window" name="In Windows"/> | ||||
|     <children xmi:id="_95Pfu3NmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.contexts.dialog" name="In Dialogs"/> | ||||
|   </rootContext> | ||||
|   <descriptors xmi:id="_KicY0HRMEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.partdescriptor.waveformviewer" label="SCViewer" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/scviewer.png" bindingContexts="_q4VSsGVNEeqSQM-A6dw9ig" allowMultiple="true" category="General" closeable="true" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.WaveformViewer"> | ||||
|   <descriptors xmi:id="_KicY0HRMEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.partdescriptor.waveformviewer" label="SCViewer" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/scviewer.png" allowMultiple="true" category="General" closeable="true" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.WaveformViewer"> | ||||
|     <tags>categoryTag:General</tags> | ||||
|     <handlers xmi:id="_BSIuEHacEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handler.navigateEventCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.NavigateEvent" command="_79rx4HabEeWwZ-9vrAR2UQ"/> | ||||
|     <handlers xmi:id="_JpdGwHXKEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handler.navigateTransCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.NavigateTrans" command="_Gn3lEHXKEeWwZ-9vrAR2UQ"/> | ||||
| @@ -204,6 +160,7 @@ | ||||
|     <handlers xmi:id="_Du1NAHcrEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handler.zoomCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ZoomHandler" command="_693GoHcqEeWwZ-9vrAR2UQ"/> | ||||
|     <handlers xmi:id="_bxt4QM3rEei6rfTGo88R-w" elementId="com.minres.scviewer.e4.application.handler.changeWaveDisplay" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ChangeWaveformDisplay" command="_FZunYM2PEei6rfTGo88R-w"/> | ||||
|     <handlers xmi:id="_bxw7kM3rEei6rfTGo88R-w" elementId="com.minres.scviewer.e4.application.handler.changeValueDisplay" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.ChangeValueDisplay" command="_4C_asM3ZEei6rfTGo88R-w"/> | ||||
|     <handlers xmi:id="_ZVHbYE-JEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handler.panCommand" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.PanHandler" command="_y2BUsE-HEeyuGJbYVZjX8w"/> | ||||
|     <menus xsi:type="menu:PopupMenu" xmi:id="_TwzrsHWSEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.popupmenu.namecontext" label="Name Menu"> | ||||
|       <children xsi:type="menu:HandledMenuItem" xmi:id="_Vco7YHWSEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledmenuitem.moveup" label="Move up" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/up_blue.png" tooltip="Move stream/waveform in list up" command="_N_sOkHXHEeWwZ-9vrAR2UQ"> | ||||
|         <visibleWhen xsi:type="ui:CoreExpression" xmi:id="_elFdcHr_EeWVM_sKoXvptg" coreExpressionId="com.minres.scviewer.e4.application.oneWaveSeleted"/> | ||||
| @@ -250,7 +207,50 @@ | ||||
|         <visibleWhen xsi:type="ui:ImperativeExpression" xmi:id="_Se1voBlEEeuiP60JNw0iiA" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.handlers.SearchHandler"/> | ||||
|       </children> | ||||
|     </menus> | ||||
|     <toolbar xmi:id="_ReeeAE-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.toolbar.3"> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_GKi7IHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.previousevent" label="Previous Event" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/previous-green.png" tooltip="Navigate to previous event in stream/waveform" command="_79rx4HabEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_XS7YYHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.10" name="com.minres.scviewer.e4.application.command.navigateEventCommand.parameter.dir" value="prev"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_GjlGMHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.nextevent" label="Next Event" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/next-green.png" tooltip="Navigate to next event in stream/waveform" command="_79rx4HabEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_ZzTqcHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.11" name="com.minres.scviewer.e4.application.command.navigateEventCommand.parameter.dir" value="next"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBarSeparator" xmi:id="_tcxaIHgwEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.toolbarseparator.4"/> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_HdKZkHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.previoustransaction" label="Previous Transaction" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/reverse_green.png" tooltip="Navigate to previous transaction" command="_Gn3lEHXKEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_cuGAkHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.12" name="com.minres.scviewer.e4.application.command.navigateTransCommand.parameter.dir" value="prev"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolControl" xmi:id="_LtQhcIuKEeWid7xO48ZBXw" elementId="com.minres.scviewer.e4.application.toolcontrol.0" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.elements.RelationTypeToolControl"/> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_H7bp8HcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.handledtoolitem.nexttransaction" label="Next Transaction" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/play_green.png" tooltip="Navigate to next transaction" command="_Gn3lEHXKEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_fiO8IHcjEeWwZ-9vrAR2UQ" elementId="com.minres.scviewer.e4.application.parameter.13" name="com.minres.scviewer.e4.application.command.navigateTransCommand.parameter.dir" value="next"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBarSeparator" xmi:id="_dOLmYE-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.toolbarseparator.0"/> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_dPFBcE-HEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handledtoolitem.panleft" label="Pan left" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/reverse_blue.png" tooltip="Pan left" command="_y2BUsE-HEeyuGJbYVZjX8w"> | ||||
|         <parameters xmi:id="_jkVBYE-JEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.parameter.14" name="com.minres.scviewer.e4.application.command.pancommand.parameter.direction" value="left"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_Z-blgE-GEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handledtoolitem.pancursor" label="Pan to cursor" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/center_blue.png" tooltip="Center on cursor" command="_y2BUsE-HEeyuGJbYVZjX8w"> | ||||
|         <parameters xmi:id="_Z-blgU-GEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.parameter.out" name="com.minres.scviewer.e4.application.command.pancommand.parameter.direction" value="cursor"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_ejt5IE-HEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handledtoolitem.panright" label="Pan right" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/play_blue.png" tooltip="Pan right" command="_y2BUsE-HEeyuGJbYVZjX8w"> | ||||
|         <parameters xmi:id="_f4awUE-JEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.parameter.out" name="com.minres.scviewer.e4.application.command.pancommand.parameter.direction" value="right"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBarSeparator" xmi:id="_b7RFoE-GEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.toolbarseparator.1"/> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_qA5D4E-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfull" label="Zoom full" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_full.png" tooltip="Zoom full range" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_qA5D4U-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.parameter.full" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="full"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_qA65EE-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomfit" label="Zoom fit" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/zoom_fit.png" tooltip="Zoom between cursor and marker" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_qA65EU-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.parameter.fit" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="fit"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:ToolBarSeparator" xmi:id="_qA8HME-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.toolbarseparator.1"/> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_qA8uQE-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomin" label="Zoom in" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magnifier_zoom_in.png" tooltip="Zoom in" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_qA8uQU-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.parameter.in" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="in"/> | ||||
|       </children> | ||||
|       <children xsi:type="menu:HandledToolItem" xmi:id="_qA98YE-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.handledtoolitem.zoomout" label="Zoom out" iconURI="platform:/plugin/com.minres.scviewer.e4.application/icons/magifier_zoom_out.png" tooltip="Zoom out" command="_693GoHcqEeWwZ-9vrAR2UQ"> | ||||
|         <parameters xmi:id="_qA98YU-DEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.parameter.out" name="com.minres.scviewer.e4.application.command.zoomcommand.parameter.level" value="out"/> | ||||
|       </children> | ||||
|     </toolbar> | ||||
|   </descriptors> | ||||
|   <snippets xsi:type="basic:Window" xmi:id="_R8mJUEhwEeyp3vLifEzGbQ" elementId="com.minres.scviewer.e4.application.window.help" selectedElement="_R8mJUUhwEeyp3vLifEzGbQ" label="SC Viewer Help" width="800" height="600"> | ||||
|     <children xsi:type="basic:Part" xmi:id="_R8mJUUhwEeyp3vLifEzGbQ" elementId="com.minres.scviewer.e4.application.part.container" contributionURI="bundleclass://com.minres.scviewer.e4.application/com.minres.scviewer.e4.application.parts.help.HelpBrowser"/> | ||||
|   </snippets> | ||||
|   <commands xmi:id="_95PfvHNmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.file.exit" commandName="Quit Command"/> | ||||
|   <commands xmi:id="_95PfwHNmEeWBq8z1Dv39LA" elementId="com.minres.scviewer.e4.application.open" commandName="Open Command"/> | ||||
|   <commands xmi:id="_95Pfw3NmEeWBq8z1Dv39LA" elementId="org.eclipse.ui.file.save" commandName="Save Command"/> | ||||
| @@ -295,6 +295,9 @@ | ||||
|   <commands xmi:id="_-9ED4B06EeuiP60JNw0iiA" elementId="com.minres.scviewer.e4.application.command.update" commandName="Update"/> | ||||
|   <commands xmi:id="_lqjIYEYEEeyPM8G0E2EYww" elementId="org.eclipse.ui.help.helpAction" commandName="Help Command"/> | ||||
|   <commands xmi:id="_Fj1gQEYoEeyKK_icsY7Xjg" elementId="com.minres.scviewer.e4.application.command.enabletxdetails" commandName="Enable Tx Details" description="Show tx details parts"/> | ||||
|   <commands xmi:id="_y2BUsE-HEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.command.pancommand" commandName="Pan Command"> | ||||
|     <parameters xmi:id="_y2BUsU-HEeyuGJbYVZjX8w" elementId="com.minres.scviewer.e4.application.command.pancommand.parameter.direction" name="direction" optional="false"/> | ||||
|   </commands> | ||||
|   <addons xmi:id="_95PfsnNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/> | ||||
|   <addons xmi:id="_95Pfs3NmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.contexts.service" contributionURI="bundleclass://org.eclipse.e4.ui.services/org.eclipse.e4.ui.services.ContextServiceAddon"/> | ||||
|   <addons xmi:id="_95PftHNmEeWBq8z1Dv39LA" elementId="org.eclipse.e4.ui.bindings.service" contributionURI="bundleclass://org.eclipse.e4.ui.bindings/org.eclipse.e4.ui.bindings.BindingServiceAddon"/> | ||||
|   | ||||
| @@ -2,7 +2,7 @@ Manifest-Version: 1.0 | ||||
| Bundle-ManifestVersion: 2 | ||||
| Bundle-Name: %Bundle-Name | ||||
| Bundle-SymbolicName: com.minres.scviewer.e4.application;singleton:=true | ||||
| Bundle-Version: 2.14.1 | ||||
| Bundle-Version: 2.15.1 | ||||
| Bundle-Vendor: %Bundle-Vendor | ||||
| Require-Bundle: javax.inject;bundle-version="1.0.0", | ||||
|  org.eclipse.core.runtime;bundle-version="3.11.1", | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.e4.application/icons/center_blue.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 600 B | 
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.e4.application/icons/next-green.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 519 B | 
| After Width: | Height: | Size: 524 B | 
| @@ -6,8 +6,8 @@ | ||||
| 	<parent> | ||||
| 		<groupId>com.minres.scviewer</groupId> | ||||
| 		<artifactId>com.minres.scviewer.parent</artifactId> | ||||
| 		<version>2.14.1</version> | ||||
| 		<relativePath>../../..</relativePath> | ||||
| 		<version>2.15.1</version> | ||||
| 		<relativePath>../..</relativePath> | ||||
| 	</parent> | ||||
| 	<packaging>eclipse-plugin</packaging> | ||||
| </project> | ||||
|   | ||||
| @@ -10,23 +10,24 @@ | ||||
|  *******************************************************************************/ | ||||
| package com.minres.scviewer.e4.application.handlers; | ||||
|  | ||||
| import org.eclipse.e4.core.di.annotations.CanExecute; | ||||
| import org.eclipse.e4.core.di.annotations.Execute; | ||||
| import org.eclipse.e4.ui.model.application.MApplication; | ||||
| import org.eclipse.e4.ui.model.application.ui.MUIElement; | ||||
| import org.eclipse.e4.ui.model.application.ui.basic.MWindow; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EModelService; | ||||
|  | ||||
| public class HelpHandler { | ||||
|  | ||||
| 	static final String DIALOG_ID="com.minres.scviewer.e4.application.dialog.onlinehelp"; //$NON-NLS-1$ | ||||
| 	static final String WINDOW_ID="com.minres.scviewer.e4.application.window.help"; //$NON-NLS-1$ | ||||
| 	@CanExecute | ||||
| 	public boolean canExecute(MApplication app) { | ||||
| 		return !app.getChildren().stream().filter(e -> e.getElementId().equals(WINDOW_ID)).findFirst().isPresent(); | ||||
| 	} | ||||
| 	 | ||||
| 	@Execute | ||||
| 	public void execute(MApplication app, /*MWindow window,*/ EModelService ms /*@Named("mdialog01.dialog.0") MDialog dialog*/) { | ||||
| //		MPart mel = (MPart) ms.find(DIALOG_ID, app); //$NON-NLS-1$ | ||||
| //		mel.setToBeRendered(true); | ||||
| //		mel.setToBeRendered(false); | ||||
| 		MUIElement w = ms.find(WINDOW_ID, app);  | ||||
| 		if(w!=null) w.setToBeRendered(true); | ||||
| 	public void execute(MApplication app, MWindow window, EModelService modelService /*@Named("mdialog01.dialog.0") MDialog dialog*/) { | ||||
| 		MWindow newWin = (MWindow)modelService.cloneSnippet(app, WINDOW_ID, null); | ||||
| 		app.getChildren().add(newWin); | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -17,7 +17,6 @@ import org.eclipse.e4.core.di.annotations.CanExecute; | ||||
| import org.eclipse.e4.core.di.annotations.Execute; | ||||
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EPartService; | ||||
| import org.eclipse.e4.ui.workbench.modeling.ESelectionService; | ||||
| import org.eclipse.jface.viewers.IStructuredSelection; | ||||
|  | ||||
| import com.minres.scviewer.database.IWaveform; | ||||
| @@ -29,21 +28,25 @@ import com.minres.scviewer.e4.application.parts.WaveformViewer; | ||||
| public class NavigateEvent { | ||||
|  | ||||
| 	final static String PARAMTER_ID="com.minres.scviewer.e4.application.command.navigateEventCommand.parameter.dir"; //$NON-NLS-1$ | ||||
| 	 | ||||
|  | ||||
| 	@CanExecute | ||||
| 	public Boolean canExecute(ESelectionService selectionService){ | ||||
| 		Object sel = selectionService.getSelection(); | ||||
| 		if( sel instanceof IStructuredSelection) { | ||||
| 			Object o= ((IStructuredSelection)sel).getFirstElement(); | ||||
| 			return o instanceof IWaveform || o instanceof ITx || o instanceof TrackEntry; | ||||
| 	public Boolean canExecute(EPartService partService){ | ||||
| 		MPart part = partService.getActivePart(); | ||||
| 		if(part.getObject() instanceof WaveformViewer){ | ||||
| 			Object sel = ((WaveformViewer)part.getObject()).getSelection(); | ||||
| 			if( sel instanceof IStructuredSelection) { | ||||
| 				if(((IStructuredSelection)sel).isEmpty()) return false; | ||||
| 				Object o= ((IStructuredSelection)sel).getFirstElement(); | ||||
| 				return o instanceof IWaveform || o instanceof ITx || o instanceof TrackEntry; | ||||
| 			} | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| 	@Execute | ||||
| 	public void execute(@Named(PARAMTER_ID) String param, EPartService partService) { | ||||
| //	public void execute(EPartService partService) { | ||||
| //		String param="next"; | ||||
| 		//	public void execute(EPartService partService) { | ||||
| 		//		String param="next"; | ||||
| 		MPart part = partService.getActivePart(); | ||||
| 		Object obj = part.getObject(); | ||||
| 		if(obj instanceof WaveformViewer){ | ||||
|   | ||||
| @@ -0,0 +1,49 @@ | ||||
| /******************************************************************************* | ||||
|  * Copyright (c) 2015-2021 MINRES Technologies GmbH and others. | ||||
|  * 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: | ||||
|  *     MINRES Technologies GmbH - initial API and implementation | ||||
|  *******************************************************************************/ | ||||
|   | ||||
| package com.minres.scviewer.e4.application.handlers; | ||||
|  | ||||
| import javax.inject.Named; | ||||
|  | ||||
| import org.eclipse.e4.core.di.annotations.CanExecute; | ||||
| import org.eclipse.e4.core.di.annotations.Execute; | ||||
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EPartService; | ||||
|  | ||||
| import com.minres.scviewer.e4.application.parts.WaveformViewer; | ||||
|  | ||||
| public class PanHandler { | ||||
|  | ||||
| 	final static String PARAMTER_ID="com.minres.scviewer.e4.application.command.pancommand.parameter.direction"; //$NON-NLS-1$ | ||||
|  | ||||
| 	@CanExecute | ||||
| 	public boolean canExecute(EPartService partService) { | ||||
| 		return true; | ||||
| 	} | ||||
| 		 | ||||
| 	@Execute | ||||
| 	public void execute(@Named(PARAMTER_ID) String level, EPartService partService) { | ||||
| 		MPart part = partService.getActivePart(); | ||||
| 		Object obj = part.getObject(); | ||||
| 		if(obj instanceof WaveformViewer){ | ||||
| 			WaveformViewer waveformViewerPart = (WaveformViewer) obj; | ||||
| 			if("left".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.pan(-1); | ||||
| 			else if("right".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.pan(+1); | ||||
| 			else if("cursor".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.pan(0); | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| } | ||||
| @@ -11,33 +11,26 @@ | ||||
|   | ||||
| package com.minres.scviewer.e4.application.handlers; | ||||
|  | ||||
| import javax.inject.Inject; | ||||
|  | ||||
| import org.eclipse.e4.core.di.annotations.CanExecute; | ||||
| import org.eclipse.e4.core.di.annotations.Execute; | ||||
| import org.eclipse.e4.core.di.annotations.Optional; | ||||
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EPartService; | ||||
|  | ||||
| import com.minres.scviewer.e4.application.parts.DesignBrowser; | ||||
| import com.minres.scviewer.e4.application.parts.WaveformViewer; | ||||
|  | ||||
| public class SelectAllHandler { | ||||
|  | ||||
| 	@Inject @Optional DesignBrowser designBrowser; | ||||
|     @CanExecute | ||||
|     public boolean canExecute(EPartService partService) { | ||||
|     	MPart part = partService.getActivePart(); | ||||
|     	return part.getObject() instanceof WaveformViewer; | ||||
|     } | ||||
|  | ||||
| 	@Execute | ||||
| 	public void execute(EPartService partService) { | ||||
| 		if(designBrowser==null) designBrowser = getListPart(partService); | ||||
| 		if(designBrowser!=null){ | ||||
| 			designBrowser.selectAllWaveforms(); | ||||
| 		} | ||||
| 		MPart part = partService.getActivePart(); | ||||
| 		if(part.getObject() instanceof WaveformViewer) | ||||
| 			((WaveformViewer) part.getObject()).selectAll(); | ||||
| 	} | ||||
|  | ||||
| 	protected DesignBrowser getListPart(EPartService partService){ | ||||
| 		MPart part = partService.getActivePart(); | ||||
| 		if(part.getObject() instanceof DesignBrowser) | ||||
| 			return (DesignBrowser) part.getObject(); | ||||
| 		else | ||||
| 			return null; | ||||
| 	}	 | ||||
|  | ||||
| } | ||||
| @@ -18,6 +18,7 @@ import org.eclipse.e4.core.di.annotations.Execute; | ||||
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; | ||||
| import org.eclipse.e4.ui.workbench.modeling.EPartService; | ||||
|  | ||||
| import com.minres.scviewer.database.ui.ZoomKind; | ||||
| import com.minres.scviewer.e4.application.parts.WaveformViewer; | ||||
|  | ||||
| public class ZoomHandler { | ||||
| @@ -35,15 +36,14 @@ public class ZoomHandler { | ||||
| 		Object obj = part.getObject(); | ||||
| 		if(obj instanceof WaveformViewer){ | ||||
| 			WaveformViewer waveformViewerPart = (WaveformViewer) obj; | ||||
| 			int zoomLevel = waveformViewerPart.getZoomLevel(); | ||||
| 			if("in".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.setZoomLevel(zoomLevel-1); | ||||
| 				waveformViewerPart.zoom(ZoomKind.IN); | ||||
| 			else if("out".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.setZoomLevel(zoomLevel+1); | ||||
| 				waveformViewerPart.zoom(ZoomKind.OUT); | ||||
| 			else if("fit".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.setZoomFit(); | ||||
| 				waveformViewerPart.zoom(ZoomKind.FIT); | ||||
| 			else if("full".equalsIgnoreCase(level)) //$NON-NLS-1$ | ||||
| 				waveformViewerPart.setZoomFull(); | ||||
| 				waveformViewerPart.zoom(ZoomKind.FULL); | ||||
| 		} | ||||
|  | ||||
| 	} | ||||
|   | ||||
| @@ -27,9 +27,6 @@ import com.minres.scviewer.e4.application.Messages; | ||||
|  */ | ||||
| public class WaveStatusBarControl extends StatusBarControl { | ||||
|  | ||||
| 	/** The Constant ZOOM_LEVEL. */ | ||||
| 	public static final String ZOOM_LEVEL="ZoomLevelUpdate"; //$NON-NLS-1$ | ||||
| 	 | ||||
| 	/** The Constant CURSOR_TIME. */ | ||||
| 	public static final String CURSOR_TIME="CursorPosUpdate"; //$NON-NLS-1$ | ||||
| 	 | ||||
| @@ -45,7 +42,7 @@ public class WaveStatusBarControl extends StatusBarControl { | ||||
|  | ||||
|  | ||||
| 	/** The zoom contribution. */ | ||||
| 	StatusLineContributionItem cursorContribution, markerContribution, markerDiffContribution, zoomContribution; | ||||
| 	StatusLineContributionItem cursorContribution, markerContribution, markerDiffContribution; | ||||
|  | ||||
| 	/** | ||||
| 	 * Instantiates a new wave status bar control. | ||||
| @@ -59,11 +56,9 @@ public class WaveStatusBarControl extends StatusBarControl { | ||||
| 		cursorContribution = new StatusLineContributionItem(Messages.WaveStatusBarControl_5, true, 20); | ||||
| 		markerContribution = new StatusLineContributionItem(Messages.WaveStatusBarControl_6, true, 20); | ||||
| 		markerDiffContribution = new StatusLineContributionItem(Messages.WaveStatusBarControl_7, true, 20); | ||||
| 		zoomContribution = new StatusLineContributionItem(Messages.WaveStatusBarControl_8, true, 8); | ||||
| 		manager.appendToGroup(StatusLineManager.BEGIN_GROUP,cursorContribution); | ||||
| 		manager.appendToGroup(StatusLineManager.BEGIN_GROUP,markerContribution); | ||||
| 		manager.appendToGroup(StatusLineManager.BEGIN_GROUP,markerDiffContribution); | ||||
| 		manager.appendToGroup(StatusLineManager.BEGIN_GROUP, zoomContribution); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -88,17 +83,6 @@ public class WaveStatusBarControl extends StatusBarControl { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the zoom event. | ||||
| 	 * | ||||
| 	 * @param text the text | ||||
| 	 * @return the zoom event | ||||
| 	 */ | ||||
| 	@Inject @Optional | ||||
| 	public void  getZoomEvent(@UIEventTopic(ZOOM_LEVEL) String text) { | ||||
| 		zoomContribution.setText(text); | ||||
| 	}  | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the cursor event. | ||||
| 	 * | ||||
|   | ||||
| @@ -85,7 +85,7 @@ HelpDialog_2=Stop | ||||
| HelpDialog_3=Refresh | ||||
| HelpDialog_4=Go | ||||
| HelpDialog_5=Address | ||||
| HelpDialog_6=https://git.minres.com/VP-Tools/SCViewer/src/branch/master/README.md\#key-shortcuts | ||||
| HelpDialog_6=https://minres.github.io/SCViewer/#key-shortcuts | ||||
| HelpDialog_7=Could not instantiate Browser:  | ||||
| marker=Marker | ||||
| marker_text=Marker TExt | ||||
|   | ||||
| @@ -226,6 +226,10 @@ public class DesignBrowser { | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 	 | ||||
| 	public Control getControl() { | ||||
| 		return top; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates the table composite. | ||||
|   | ||||
| @@ -94,6 +94,7 @@ import com.minres.scviewer.database.ui.IWaveformView; | ||||
| import com.minres.scviewer.database.ui.TrackEntry; | ||||
| import com.minres.scviewer.database.ui.TrackEntry.ValueDisplay; | ||||
| import com.minres.scviewer.database.ui.TrackEntry.WaveDisplay; | ||||
| import com.minres.scviewer.database.ui.ZoomKind; | ||||
| import com.minres.scviewer.database.ui.swt.Constants; | ||||
| import com.minres.scviewer.database.ui.swt.IToolTipContentProvider; | ||||
| import com.minres.scviewer.database.ui.swt.IToolTipHelpTextProvider; | ||||
| @@ -131,7 +132,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	protected static final String SHOWN_CURSOR = "SHOWN_CURSOR"; //$NON-NLS-1$ | ||||
|  | ||||
| 	/** The Constant ZOOM_LEVEL. */ | ||||
| 	protected static final String ZOOM_LEVEL = "ZOOM_LEVEL"; //$NON-NLS-1$ | ||||
| 	protected static final String SCALING_FACTOR = "SCALING_FACTOR"; //$NON-NLS-1$ | ||||
|  | ||||
| 	/** The Constant BASE_LINE_TIME. */ | ||||
| 	protected static final String BASE_LINE_TIME = "BASE_LINE_TIME"; //$NON-NLS-1$ | ||||
| @@ -151,9 +152,6 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	/** The Constant TX_DETAILS_SHOWN. */ | ||||
| 	protected static final String TX_DETAILS_SHOWN = "TX_DETAILS_SHOWN"; //$NON-NLS-1$ | ||||
|  | ||||
| 	/** The zoom level. */ | ||||
| 	private String[] zoomLevel; | ||||
|  | ||||
| 	/** The Constant ID. */ | ||||
| 	public static final String ID = "com.minres.scviewer.ui.TxEditorPart"; //$NON-NLS-1$ | ||||
|  | ||||
| @@ -299,15 +297,15 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
|  | ||||
| 		waveformPane.addPropertyChangeListener(IWaveformView.CURSOR_PROPERTY, evt -> { | ||||
| 			Long time = (Long) evt.getNewValue(); | ||||
| 			eventBroker.post(WaveStatusBarControl.CURSOR_TIME, waveformPane.getScaledTime(time)); | ||||
| 			long marker = waveformPane.getMarkerTime(waveformPane.getSelectedMarkerId()); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getScaledTime(time - marker)); | ||||
| 			eventBroker.post(WaveStatusBarControl.CURSOR_TIME, waveformPane.getWaveformZoom().timeToString(time)); | ||||
| 			long marker = waveformPane.getMarkerTime(waveformPane.getSelectedMarker()); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getWaveformZoom().timeToString(time - marker)); | ||||
| 		}); | ||||
| 		waveformPane.addPropertyChangeListener(IWaveformView.MARKER_PROPERTY, evt -> { | ||||
| 			Long time = (Long) evt.getNewValue(); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_TIME, waveformPane.getScaledTime(time)); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_TIME, waveformPane.getWaveformZoom().timeToString(time)); | ||||
| 			long cursor = waveformPane.getCursorTime(); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getScaledTime(cursor - time)); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getWaveformZoom().timeToString(cursor - time)); | ||||
| 		}); | ||||
|  | ||||
| 		waveformPane.addSelectionChangedListener(event -> { | ||||
| @@ -319,17 +317,14 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 		waveformPane.getWaveformControl().addListener(SWT.KeyDown, e -> { | ||||
| 			if((e.stateMask&SWT.MOD3)!=0) { // Alt key | ||||
| 			} else if((e.stateMask&SWT.MOD1)!=0) { //Ctrl/Cmd | ||||
| 				int zoomlevel = waveformPane.getZoomLevel(); | ||||
| 				switch(e.keyCode) { | ||||
| 				case '+': | ||||
| 				case SWT.KEYPAD_ADD: | ||||
| 					if(zoomlevel>0) | ||||
| 						waveformPane.setZoomLevel(zoomlevel-1); | ||||
| 					waveformPane.getWaveformZoom().zoom(ZoomKind.IN); | ||||
| 					return; | ||||
| 				case '-': | ||||
| 				case SWT.KEYPAD_SUBTRACT: | ||||
| 					if(zoomlevel<waveformPane.getZoomLevels().length-1) | ||||
| 						waveformPane.setZoomLevel(zoomlevel+1); | ||||
| 					waveformPane.getWaveformZoom().zoom(ZoomKind.OUT); | ||||
| 					return; | ||||
| 				case SWT.ARROW_UP: | ||||
| 					waveformPane.moveSelectedTrack(-1); | ||||
| @@ -337,6 +332,8 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 				case SWT.ARROW_DOWN: | ||||
| 					waveformPane.moveSelectedTrack(1); | ||||
| 					return; | ||||
| 				case 'a': | ||||
| 					selectAll(); | ||||
| 				default: | ||||
| 					break; | ||||
| 				} | ||||
| @@ -379,7 +376,6 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		zoomLevel = waveformPane.getZoomLevels(); | ||||
| 		checkForUpdates = store.getBoolean(PreferenceConstants.DATABASE_RELOAD, true); | ||||
| 		filesToLoad = new ArrayList<>(); | ||||
| 		persistedState = part.getPersistedState(); | ||||
| @@ -390,7 +386,6 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 		} | ||||
| 		if (!filesToLoad.isEmpty()) | ||||
| 			loadDatabase(persistedState); | ||||
| 		eventBroker.post(WaveStatusBarControl.ZOOM_LEVEL, zoomLevel[waveformPane.getZoomLevel()]); | ||||
| 		menuService.registerContextMenu(waveformPane.getNameControl(), MENU_CONTEXT); | ||||
| 		menuService.registerContextMenu(waveformPane.getValueControl(),	MENU_CONTEXT); | ||||
| 		menuService.registerContextMenu(waveformPane.getWaveformControl(), MENU_CONTEXT); | ||||
| @@ -748,8 +743,8 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			persistingState.put(SHOWN_CURSOR + index, Long.toString(cursor.getTime())); | ||||
| 			index++; | ||||
| 		} | ||||
| 		persistingState.put(ZOOM_LEVEL, Integer.toString(waveformPane.getZoomLevel())); | ||||
| 		persistingState.put(BASE_LINE_TIME, Long.toString(waveformPane.getBaselineTime())); | ||||
| 		persistingState.put(SCALING_FACTOR, Long.toString(waveformPane.getWaveformZoom().getScale())); | ||||
| 		persistingState.put(BASE_LINE_TIME, Long.toString(waveformPane.getWaveformZoom().getMinVisibleTime())); | ||||
|  | ||||
| 		// get selected transaction	of a stream	 | ||||
| 		ISelection selection = waveformPane.getSelection(); | ||||
| @@ -792,18 +787,15 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	protected void restoreWaveformViewerState(Map<String, String> state) { | ||||
| 		Integer waves = state.containsKey(SHOWN_WAVEFORM+"S") ? Integer.parseInt(state.get(SHOWN_WAVEFORM + "S")):0; //$NON-NLS-1$ //$NON-NLS-2$ | ||||
| 		List<TrackEntry> trackEntries = new LinkedList<>(); | ||||
| 		List<TrackEntry> selectedTrackEntries = new LinkedList<>(); | ||||
| 		for (int i = 0; i < waves; i++) { | ||||
| 			IWaveform waveform = database.getStreamByName(state.get(SHOWN_WAVEFORM + i)); | ||||
| 			if (waveform != null) { | ||||
| 				TrackEntry trackEntry = waveformPane.addWaveform(waveform, -1); | ||||
| 				//check if t is selected | ||||
| 				boolean isSelected = Boolean.parseBoolean(state.get(SHOWN_WAVEFORM + i + WAVEFORM_SELECTED)); | ||||
| 				if(isSelected) { | ||||
| 					trackEntry.selected = true; | ||||
| 				} else { | ||||
| 					trackEntry.selected = false; | ||||
| 				} | ||||
| 				trackEntries.add(trackEntry); | ||||
| 				if(Boolean.parseBoolean(state.get(SHOWN_WAVEFORM + i + WAVEFORM_SELECTED))) | ||||
| 					selectedTrackEntries.add(trackEntry); | ||||
| 				String v = state.get(SHOWN_WAVEFORM + i + VALUE_DISPLAY); | ||||
| 				if(v!=null) | ||||
| 					trackEntry.valueDisplay=ValueDisplay.valueOf(v); | ||||
| @@ -820,17 +812,17 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 				cursors.get(i).setTime(time); | ||||
| 			} | ||||
| 		} | ||||
| 		if (state.containsKey(ZOOM_LEVEL)) { | ||||
| 		if (state.containsKey(SCALING_FACTOR)) { | ||||
| 			try { | ||||
| 				Integer scale = Integer.parseInt(state.get(ZOOM_LEVEL)); | ||||
| 				waveformPane.setZoomLevel(scale); | ||||
| 				long scale = Long.parseLong(state.get(SCALING_FACTOR)); | ||||
| 				waveformPane.getWaveformZoom().setScale(scale); | ||||
| 			} catch (NumberFormatException e) { | ||||
| 			} | ||||
| 		} | ||||
| 		if (state.containsKey(BASE_LINE_TIME)) { | ||||
| 			try { | ||||
| 				Long scale = Long.parseLong(state.get(BASE_LINE_TIME)); | ||||
| 				waveformPane.setBaselineTime(scale); | ||||
| 				waveformPane.getWaveformZoom().setMinVisibleTime(scale); | ||||
| 			} catch (NumberFormatException e) { | ||||
| 			} | ||||
| 		} | ||||
| @@ -861,6 +853,8 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			} catch (NumberFormatException e) { | ||||
| 			} | ||||
| 		} | ||||
| 		ISelection sel = new StructuredSelection(selectedTrackEntries); | ||||
| 		waveformPane.setSelection(sel); | ||||
| 		updateAll(); | ||||
| 	} | ||||
|  | ||||
| @@ -869,12 +863,11 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	 */ | ||||
| 	private void updateAll() { | ||||
| 		eventBroker.post(ACTIVE_WAVEFORMVIEW, this); | ||||
| 		eventBroker.post(WaveStatusBarControl.ZOOM_LEVEL, zoomLevel[waveformPane.getZoomLevel()]); | ||||
| 		long cursor = waveformPane.getCursorTime(); | ||||
| 		long marker = waveformPane.getMarkerTime(waveformPane.getSelectedMarkerId()); | ||||
| 		eventBroker.post(WaveStatusBarControl.CURSOR_TIME, waveformPane.getScaledTime(cursor)); | ||||
| 		eventBroker.post(WaveStatusBarControl.MARKER_TIME, waveformPane.getScaledTime(marker)); | ||||
| 		eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getScaledTime(cursor - marker)); | ||||
| 		long marker = waveformPane.getMarkerTime(waveformPane.getSelectedMarker()); | ||||
| 		eventBroker.post(WaveStatusBarControl.CURSOR_TIME, waveformPane.getWaveformZoom().timeToString(cursor)); | ||||
| 		eventBroker.post(WaveStatusBarControl.MARKER_TIME, waveformPane.getWaveformZoom().timeToString(marker)); | ||||
| 		eventBroker.post(WaveStatusBarControl.MARKER_DIFF, waveformPane.getWaveformZoom().timeToString(cursor - marker)); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -1045,44 +1038,35 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets the zoom level. | ||||
| 	 * | ||||
| 	 * @param level the new zoom level | ||||
| 	 * Execute the zoom according to kind. | ||||
| 	 *  | ||||
| 	 * @param kind the type of zoom to execute | ||||
| 	 */ | ||||
| 	public void setZoomLevel(Integer level) { | ||||
| 		if (level < 0) | ||||
| 			level = 0; | ||||
| 		if (level > zoomLevel.length - 1) | ||||
| 			level = zoomLevel.length - 1; | ||||
| 		waveformPane.setZoomLevel(level); | ||||
| 	public void zoom(ZoomKind kind) { | ||||
| 		waveformPane.getWaveformZoom().zoom(kind); | ||||
| 		updateAll(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets the zoom fit. | ||||
| 	 * Execute the zoom kind. | ||||
| 	 *  | ||||
| 	 * @param direction the direction of the pan (-1, 0, 1) | ||||
| 	 */ | ||||
| 	public void setZoomFit() { | ||||
| 		waveformPane.setZoomLevel(-2); | ||||
| 	public void pan(int direction) { | ||||
| 		switch(direction) { | ||||
| 		case -1:  | ||||
| 			waveformPane.scrollHorizontal(-10); | ||||
| 			return; | ||||
| 		case 1: | ||||
| 			waveformPane.scrollHorizontal(10); | ||||
| 			return; | ||||
| 		case 0: | ||||
| 			waveformPane.scrollTo(IWaveformView.CURSOR_POS); | ||||
| 			return; | ||||
| 		} | ||||
| 		updateAll(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets the zoom fit. | ||||
| 	 */ | ||||
| 	public void setZoomFull() { | ||||
| 		waveformPane.setZoomLevel(-1); | ||||
| 		updateAll(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the zoom level. | ||||
| 	 * | ||||
| 	 * @return the zoom level | ||||
| 	 */ | ||||
| 	public int getZoomLevel() { | ||||
| 		return waveformPane.getZoomLevel(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the selection. | ||||
| 	 * | ||||
| @@ -1111,7 +1095,7 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	 * @return the scaled time | ||||
| 	 */ | ||||
| 	public String getScaledTime(Long time) { | ||||
| 		return waveformPane.getScaledTime(time); | ||||
| 		return waveformPane.getWaveformZoom().timeToString(time); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| @@ -1237,7 +1221,6 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 	public void widgetDisposed(DisposeEvent e) { | ||||
| 		disposeListenerNumber -= 1; | ||||
| 		if( disposeListenerNumber == 0) {  //if the last tab is closed, reset statusbar | ||||
| 			eventBroker.post(WaveStatusBarControl.ZOOM_LEVEL, null); | ||||
| 			eventBroker.post(WaveStatusBarControl.CURSOR_TIME, null); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_TIME, null); | ||||
| 			eventBroker.post(WaveStatusBarControl.MARKER_DIFF, null); | ||||
| @@ -1269,4 +1252,11 @@ public class WaveformViewer implements IFileChangeListener, IPreferenceChangeLis | ||||
| 			} catch (BackingStoreException e) {} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	public void selectAll() { | ||||
| 		List<TrackEntry> entries = waveformPane.getStreamList(); | ||||
| 		ISelection sel = new StructuredSelection(entries); | ||||
| 		waveformPane.setSelection(sel); | ||||
| 		designBrowser.selectAllWaveforms(); | ||||
| 	} | ||||
| } | ||||
| @@ -5,6 +5,8 @@ import java.io.File; | ||||
| import javax.annotation.PostConstruct; | ||||
| import javax.inject.Inject; | ||||
|  | ||||
| import org.eclipse.e4.core.contexts.IEclipseContext; | ||||
| import org.eclipse.e4.ui.model.application.ui.MUIElement; | ||||
| import org.eclipse.jface.dialogs.MessageDialog; | ||||
| import org.eclipse.jface.resource.ImageDescriptor; | ||||
| import org.eclipse.jface.resource.ResourceLocator; | ||||
| @@ -29,6 +31,10 @@ import com.minres.scviewer.e4.application.Messages; | ||||
|  | ||||
| public class HelpBrowser { | ||||
|  | ||||
| 	@Inject IEclipseContext ctx; | ||||
| 	 | ||||
| 	@Inject MUIElement element; | ||||
| 	 | ||||
| 	private static void decorateItem(ToolItem item, String label, String imageName) { | ||||
| 		String fullpath = File.separator+"icons"+File.separator+imageName; //$NON-NLS-1$ | ||||
| 		ImageDescriptor descr =  ResourceLocator.imageDescriptorFromBundle("com.minres.scviewer.e4.application", fullpath).orElse(null); //$NON-NLS-1$ | ||||
| @@ -41,13 +47,12 @@ public class HelpBrowser { | ||||
| 		item.setData(label); | ||||
| 	} | ||||
|  | ||||
| 	@Inject | ||||
| 	public HelpBrowser() { | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	@PostConstruct | ||||
| 	protected Control createComposite(Composite container) { | ||||
| //		container.getShell().addListener(SWT.Close, e -> { | ||||
| //			e.doit= false; | ||||
| //			element.setVisible(false); | ||||
| //		}); | ||||
| 		GridLayout gridLayout = new GridLayout(); | ||||
| 		gridLayout.numColumns = 3; | ||||
| 		container.setLayout(gridLayout); | ||||
| @@ -141,6 +146,8 @@ public class HelpBrowser { | ||||
| 		} | ||||
| 		return container; | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	 | ||||
| 	void handleShellCloseEvent(){ | ||||
| 		 | ||||
| 	} | ||||
| } | ||||
| @@ -5,7 +5,7 @@ | ||||
|    <extension | ||||
|          point="org.eclipse.ui.views"> | ||||
|       <category | ||||
|             name="TxViewer" | ||||
|             name="SCViewer" | ||||
|             id="com.minres.scviewer.ui"> | ||||
|       </category> | ||||
|    </extension> | ||||
| @@ -139,19 +139,7 @@ | ||||
|                </visibleWhen> | ||||
|             </command> | ||||
|            <command | ||||
|                  commandId="com.minres.scviewer.ui.zoom" | ||||
|                  id="com.minres.scviewer.ui.zoom.command" | ||||
|                  style="pulldown" | ||||
|                  tooltip="Set zoom level"> | ||||
|               <visibleWhen | ||||
|                     checkEnabled="false"> | ||||
|                  <reference | ||||
|                        definitionId="com.minres.scviewer.ui.waveEditorActive"> | ||||
|                  </reference> | ||||
|               </visibleWhen> | ||||
|            </command> | ||||
|            <command | ||||
|                  commandId="com.minres.scviewer.ui.zoomin" | ||||
|                  commandId="com.minres.scviewer.ui.zoom.in" | ||||
|                  label="Zoom in" | ||||
|                  style="push" | ||||
|                  tooltip="Zoom into"> | ||||
| @@ -163,7 +151,7 @@ | ||||
|               </visibleWhen> | ||||
|            </command> | ||||
|            <command | ||||
|                  commandId="com.minres.scviewer.ui.zoomout" | ||||
|                  commandId="com.minres.scviewer.ui.zoom.out" | ||||
|                  label="Zoom out" | ||||
|                  style="push" | ||||
|                  tooltip="Zoom out of"> | ||||
| @@ -176,119 +164,6 @@ | ||||
|            </command> | ||||
|          </toolbar> | ||||
|       </menuContribution> | ||||
|       <menuContribution | ||||
|             locationURI="menu:com.minres.scviewer.ui.zoom.command"> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="100ps" | ||||
|                style="push" | ||||
|                tooltip="Resolution 100ps"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="5"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="1ns" | ||||
|                style="push" | ||||
|                tooltip="Resolution 1ns"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="6"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="10ns" | ||||
|                style="push" | ||||
|                tooltip="Resolution 10ns"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="7"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="100ns" | ||||
|                style="push" | ||||
|                tooltip="Resolution 100ns"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="8"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="1µs" | ||||
|                style="push" | ||||
|                tooltip="Resolution 1us"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="9"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="10µs" | ||||
|                style="push" | ||||
|                tooltip="Resolution 10us"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="10"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="100µs" | ||||
|                style="push" | ||||
|                tooltip="Resolution 100us"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="11"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="1ms" | ||||
|                style="push" | ||||
|                tooltip="Resolution 1ms"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="12"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="10ms" | ||||
|                style="push" | ||||
|                tooltip="Resolution 10ms"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="13"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="100ms" | ||||
|                style="push" | ||||
|                tooltip="Resolution 100ms"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="14"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoom" | ||||
|                label="1s" | ||||
|                style="push" | ||||
|                tooltip="Resolution 1s"> | ||||
|             <parameter | ||||
|                   name="com.minres.scviewer.ui.zoom.level" | ||||
|                   value="15"> | ||||
|             </parameter> | ||||
|          </command> | ||||
|       </menuContribution> | ||||
|       <menuContribution | ||||
|             allPopups="false" | ||||
|             locationURI="popup:com.minres.scviewer.ui.TxEditorPart"> | ||||
| @@ -305,7 +180,7 @@ | ||||
|             </visibleWhen> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoomin" | ||||
|                commandId="com.minres.scviewer.ui.zoom.in" | ||||
|                label="Zoom in" | ||||
|                style="push" | ||||
|                tooltip="Zoom into"> | ||||
| @@ -317,7 +192,7 @@ | ||||
|             </visibleWhen> | ||||
|          </command> | ||||
|          <command | ||||
|                commandId="com.minres.scviewer.ui.zoomout" | ||||
|                commandId="com.minres.scviewer.ui.zoom.out" | ||||
|                label="Zoom out" | ||||
|                style="push" | ||||
|                tooltip="Zoom out of"> | ||||
| @@ -367,24 +242,21 @@ | ||||
|             name="Prev"> | ||||
|       </command> | ||||
|       <command | ||||
|             defaultHandler="com.minres.scviewer.ui.handler.Zoom" | ||||
|             description="Set the zoom level" | ||||
|             id="com.minres.scviewer.ui.zoom" | ||||
|             name="Zoom"> | ||||
|          <commandParameter | ||||
|                id="com.minres.scviewer.ui.zoom.level" | ||||
|                name="level" | ||||
|                optional="true"> | ||||
|          </commandParameter> | ||||
|       </command> | ||||
|       <command | ||||
|             id="com.minres.scviewer.ui.zoomin" | ||||
|             id="com.minres.scviewer.ui.zoom.in" | ||||
|             name="Zoom in"> | ||||
|       </command> | ||||
|       <command | ||||
|             id="com.minres.scviewer.ui.zoomout" | ||||
|             id="com.minres.scviewer.ui.zoom.out" | ||||
|             name="Zoom out"> | ||||
|       </command> | ||||
|       <command | ||||
|             id="com.minres.scviewer.ui.zoom.fit" | ||||
|             name="Zoom fit"> | ||||
|       </command> | ||||
|       <command | ||||
|             id="com.minres.scviewer.ui.zoom.full" | ||||
|             name="Zoom full"> | ||||
|       </command> | ||||
|       <command | ||||
|             id="com.minres.scviewer.ui.removeWave" | ||||
|             name="Remove wave"> | ||||
| @@ -411,8 +283,8 @@ | ||||
|          </enabledWhen> | ||||
|       </handler> | ||||
|       <handler | ||||
|             class="com.minres.scviewer.ui.handler.ZoomInOut" | ||||
|             commandId="com.minres.scviewer.ui.zoomin"> | ||||
|             class="com.minres.scviewer.ui.handler.Zoom" | ||||
|             commandId="com.minres.scviewer.ui.zoom.in"> | ||||
|          <enabledWhen> | ||||
|             <reference | ||||
|                   definitionId="com.minres.scviewer.ui.waveEditorActive"> | ||||
| @@ -420,8 +292,8 @@ | ||||
|          </enabledWhen> | ||||
|       </handler> | ||||
|       <handler | ||||
|             class="com.minres.scviewer.ui.handler.ZoomInOut" | ||||
|             commandId="com.minres.scviewer.ui.zoomout"> | ||||
|             class="com.minres.scviewer.ui.handler.Zoom" | ||||
|             commandId="com.minres.scviewer.ui.zoom.out"> | ||||
|          <enabledWhen> | ||||
|             <reference | ||||
|                   definitionId="com.minres.scviewer.ui.waveEditorActive"> | ||||
| @@ -493,15 +365,11 @@ | ||||
|             icon="res/images/next-green.png"> | ||||
|       </image> | ||||
|       <image | ||||
|             commandId="com.minres.scviewer.ui.zoom" | ||||
|             icon="res/images/zoom.png"> | ||||
|       </image> | ||||
|       <image | ||||
|             commandId="com.minres.scviewer.ui.zoomin" | ||||
|             commandId="com.minres.scviewer.ui.zoom.in" | ||||
|             icon="res/images/zoom_in.png"> | ||||
|       </image> | ||||
|       <image | ||||
|             commandId="com.minres.scviewer.ui.zoomout" | ||||
|             commandId="com.minres.scviewer.ui.zoom.out" | ||||
|             icon="res/images/zoom_out.png"> | ||||
|       </image> | ||||
|       <image | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
| 	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
| 	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|   <packaging>eclipse-plugin</packaging> | ||||
|   <version>1.1.0-SNAPSHOT</version> | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								plugins/com.minres.scviewer.ui/res/images/wave.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.2 KiB | 
| @@ -50,6 +50,7 @@ import com.minres.scviewer.database.IWaveformDbFactory; | ||||
| import com.minres.scviewer.database.ui.GotoDirection; | ||||
| import com.minres.scviewer.database.ui.IWaveformView; | ||||
| import com.minres.scviewer.database.ui.TrackEntry; | ||||
| import com.minres.scviewer.database.ui.ZoomKind; | ||||
| import com.minres.scviewer.database.ui.swt.WaveformViewFactory; | ||||
| import com.minres.scviewer.ui.views.TxOutlinePage; | ||||
|  | ||||
| @@ -66,13 +67,6 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage | ||||
| 			waveformDbFactory=null; | ||||
| 	} | ||||
| 	 | ||||
| 	private final static String[] zoomLevel={ | ||||
| 		"1fs", "10fs", "100fs", | ||||
| 		"1ps", "10ps", "100ps", | ||||
| 		"1ns", "10ns", "100ns", | ||||
| 		"1µs", "10µs", "10µs", | ||||
| 		"1ms", "10ms", "100ms", "1s"}; | ||||
| 		 | ||||
| 	public static final String ID = "com.minres.scviewer.ui.TxEditorPart"; //$NON-NLS-1$ | ||||
|  | ||||
| 	public static final String WAVE_ACTION_ID = "com.minres.scviewer.ui.action.AddToWave"; | ||||
| @@ -85,7 +79,6 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage | ||||
| 	private Composite myParent; | ||||
|  | ||||
|     private StatusLineContributionItem cursorStatusLineItem; | ||||
| 	private StatusLineContributionItem zoomStatusLineItem; | ||||
|  | ||||
| 	public TxEditorPart() { | ||||
| 	} | ||||
| @@ -132,7 +125,6 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage | ||||
| 				} | ||||
| 			} | ||||
| 		}).run(); | ||||
| 		zoomStatusLineItem.setText("Zoom level: "+zoomLevel[waveformView.getZoomLevel()]); | ||||
| 		cursorStatusLineItem.setText("Cursor: "+ waveformView.getCursorTime()/1000000+"ns"); | ||||
| 		MenuManager menuMgr = new MenuManager("#PopupMenu"); | ||||
| //		menuMgr.setRemoveAllWhenShown(true); | ||||
| @@ -306,11 +298,9 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage | ||||
| 		// Initialize the editor part | ||||
| 		setSite(site); | ||||
| 		setInput(input); | ||||
| 		zoomStatusLineItem = new StatusLineContributionItem("TxEditorZoomContributionItem"); | ||||
|         cursorStatusLineItem = new StatusLineContributionItem("TxEditorCursorContributionItem"); | ||||
| 		IActionBars actionBars = getEditorSite().getActionBars(); | ||||
| 		IStatusLineManager manager = actionBars.getStatusLineManager(); | ||||
| 		manager.add(zoomStatusLineItem); | ||||
|         manager.add(cursorStatusLineItem); | ||||
| 		actionBars.updateActionBars(); | ||||
| 	} | ||||
| @@ -388,16 +378,8 @@ public class TxEditorPart extends EditorPart implements ITabbedPropertySheetPage | ||||
| 		waveformView.moveSelection( next);		 | ||||
| 	} | ||||
|  | ||||
| 	public void setZoomLevel(Integer level) { | ||||
| 		waveformView.setZoomLevel(level); | ||||
| 	} | ||||
|  | ||||
| 	public void setZoomFit() { | ||||
| 		waveformView.setZoomLevel(6);		 | ||||
| 	} | ||||
|  | ||||
| 	public int getZoomLevel() { | ||||
| 		return waveformView.getZoomLevel(); | ||||
| 	public void setZoom(ZoomKind kind) { | ||||
| 		waveformView.getWaveformZoom().zoom(kind);		 | ||||
| 	} | ||||
|  | ||||
| 	public void removeSelected() { | ||||
|   | ||||
| @@ -16,25 +16,30 @@ import org.eclipse.core.commands.ExecutionException; | ||||
| import org.eclipse.ui.IEditorPart; | ||||
| import org.eclipse.ui.handlers.HandlerUtil; | ||||
|  | ||||
| import com.minres.scviewer.database.ui.ZoomKind; | ||||
| import com.minres.scviewer.ui.TxEditorPart; | ||||
|  | ||||
| public class Zoom extends AbstractHandler { | ||||
| 	private static final String PARM_MSG = "com.minres.scviewer.ui.zoom.level"; | ||||
| 	private static final String ZOOMIN_ID   = "com.minres.scviewer.ui.zoom.in"; | ||||
| 	private static final String ZOOMOUT_ID  = "com.minres.scviewer.ui.zoom.out"; | ||||
| 	private static final String ZOOMFIT_ID  = "com.minres.scviewer.ui.zoom.fit"; | ||||
| 	private static final String ZOOMFULL_ID = "com.minres.scviewer.ui.zoom.full"; | ||||
|  | ||||
| 	@Override | ||||
| 	public Object execute(ExecutionEvent event) throws ExecutionException { | ||||
| 		IEditorPart editor = HandlerUtil.getActiveEditor(event); | ||||
| 	    String msg = event.getParameter(PARM_MSG); | ||||
| 	    if (msg == null) { | ||||
| 			if(editor instanceof TxEditorPart){ | ||||
| 				((TxEditorPart)editor).setZoomFit(); | ||||
| 			} | ||||
| 	    } else { | ||||
| 	    	Integer level = Integer.parseInt(msg); | ||||
| 			if(editor instanceof TxEditorPart){ | ||||
| 				((TxEditorPart)editor).setZoomLevel(level); | ||||
| 			} | ||||
| 	    } | ||||
| 		if(editor instanceof TxEditorPart){ | ||||
| 		    String id = event.getCommand().getId(); | ||||
| 			TxEditorPart txEditor=(TxEditorPart) editor; | ||||
| 		    if (ZOOMIN_ID.compareTo(id) == 0) | ||||
| 		    	txEditor.setZoom(ZoomKind.IN); | ||||
| 		    else if(ZOOMOUT_ID.compareTo(id) == 0) | ||||
| 		    	txEditor.setZoom(ZoomKind.OUT); | ||||
| 		    else if(ZOOMFIT_ID.compareTo(id) == 0) | ||||
| 		    	txEditor.setZoom(ZoomKind.FIT); | ||||
| 		    else if(ZOOMFULL_ID.compareTo(id) == 0) | ||||
| 		    	txEditor.setZoom(ZoomKind.FULL); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1,39 +0,0 @@ | ||||
| /******************************************************************************* | ||||
|  * Copyright (c) 2015-2021 MINRES Technologies GmbH and others. | ||||
|  * 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: | ||||
|  *     MINRES Technologies GmbH - initial API and implementation | ||||
|  *******************************************************************************/ | ||||
| package com.minres.scviewer.ui.handler; | ||||
|  | ||||
| import org.eclipse.core.commands.AbstractHandler; | ||||
| import org.eclipse.core.commands.ExecutionEvent; | ||||
| import org.eclipse.core.commands.ExecutionException; | ||||
| import org.eclipse.ui.IEditorPart; | ||||
| import org.eclipse.ui.handlers.HandlerUtil; | ||||
|  | ||||
| import com.minres.scviewer.ui.TxEditorPart; | ||||
|  | ||||
| public class ZoomInOut extends AbstractHandler { | ||||
| 	private static final String ZOOMIN_ID = "com.minres.scviewer.ui.zoomin"; | ||||
| 	private static final String ZOOMOUT_ID= "com.minres.scviewer.ui.zoomout"; | ||||
|  | ||||
| 	@Override | ||||
| 	public Object execute(ExecutionEvent event) throws ExecutionException { | ||||
| 		IEditorPart editor = HandlerUtil.getActiveEditor(event); | ||||
| 		if(editor instanceof TxEditorPart){ | ||||
| 		    String id = event.getCommand().getId(); | ||||
| 			TxEditorPart txEditor=(TxEditorPart) editor; | ||||
| 		    if (ZOOMIN_ID.compareTo(id) == 0) | ||||
| 		    	txEditor.setZoomLevel(txEditor.getZoomLevel()-1); | ||||
| 		    else if(ZOOMOUT_ID.compareTo(id) == 0) | ||||
| 		    	txEditor.setZoomLevel(txEditor.getZoomLevel()+1); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| } | ||||
							
								
								
									
										152
									
								
								pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,152 @@ | ||||
| <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> | ||||
| 	<groupId>com.minres.scviewer</groupId> | ||||
| 	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
| 	<version>2.15.1</version> | ||||
| 	<packaging>pom</packaging> | ||||
| 	<modules> | ||||
| 		<module>releng/com.minres.scviewer.target</module> | ||||
| 		<module>plugins/com.minres.scviewer.database</module> | ||||
| 		<module>plugins/com.minres.scviewer.database.sqlite</module> | ||||
| 		<module>plugins/com.minres.scviewer.database.text</module> | ||||
| 		<module>plugins/com.minres.scviewer.database.vcd</module> | ||||
| 		<module>tests/com.minres.scviewer.database.test</module> | ||||
| 		<module>plugins/com.minres.scviewer.database.ui.swt</module> | ||||
| 		<module>plugins/com.minres.scviewer.e4.application</module> | ||||
| 		<module>plugins/com.minres.scviewer.ui</module> | ||||
| 		<module>features/com.minres.scviewer.database.feature</module> | ||||
| 		<module>features/com.minres.scviewer.ui.feature</module> | ||||
| 		<module>features/com.minres.scviewer.feature</module> | ||||
| 		<module>features/com.minres.scviewer.e4.platform.feature</module> | ||||
| 		<module>features/com.minres.scviewer.e4.feature</module> | ||||
| 		<module>releng/com.minres.scviewer.updateSite</module> | ||||
| 		<module>products/com.minres.scviewer.e4.product</module> | ||||
| 	</modules> | ||||
|  | ||||
| 	<properties> | ||||
| 		<tycho-version>1.5.0</tycho-version> | ||||
| 		<groovy-eclipse-compiler-version>3.6.0-03</groovy-eclipse-compiler-version> | ||||
| 		<groovy-eclipse-batch-version>3.0.3-01</groovy-eclipse-batch-version> | ||||
| 		<software.download.area>${project.basedir}/../../..</software.download.area> | ||||
| 	</properties> | ||||
|  | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>org.codehaus.mojo</groupId> | ||||
| 				<artifactId>build-helper-maven-plugin</artifactId> | ||||
| 				<version>3.2.0</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<id>parse-version</id> | ||||
| 						<goals> | ||||
| 							<goal>parse-version</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 			</plugin> | ||||
| 			<plugin> | ||||
| 				<groupId>org.eclipse.tycho</groupId> | ||||
| 				<artifactId>tycho-maven-plugin</artifactId> | ||||
| 				<version>${tycho-version}</version> | ||||
| 				<extensions>true</extensions> | ||||
| 			</plugin> | ||||
| 			<plugin> | ||||
| 				<groupId>org.eclipse.tycho</groupId> | ||||
| 				<artifactId>tycho-versions-plugin</artifactId> | ||||
| 				<version>${tycho-version}</version> | ||||
| 			</plugin> | ||||
|  | ||||
| 			<plugin> | ||||
| 				<groupId>org.eclipse.tycho</groupId> | ||||
| 				<artifactId>target-platform-configuration</artifactId> | ||||
| 				<version>${tycho-version}</version> | ||||
| 				<configuration> | ||||
| 					<target> | ||||
| 						<artifact> | ||||
| 							<groupId>com.minres.scviewer</groupId> | ||||
| 							<artifactId>com.minres.scviewer.target</artifactId> | ||||
| 							<version>2.15.1</version> | ||||
| 						</artifact> | ||||
| 					</target> | ||||
| 					<environments> | ||||
| 						<environment> | ||||
| 							<os>linux</os> | ||||
| 							<ws>gtk</ws> | ||||
| 							<arch>x86_64</arch> | ||||
| 						</environment> | ||||
| 						<environment> | ||||
| 							<os>win32</os> | ||||
| 							<ws>win32</ws> | ||||
| 							<arch>x86_64</arch> | ||||
| 						</environment> | ||||
| 						<environment> | ||||
| 							<os>macosx</os> | ||||
| 							<ws>cocoa</ws> | ||||
| 							<arch>x86_64</arch> | ||||
| 						</environment> | ||||
| 					</environments> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 			<plugin> | ||||
| 				<groupId>org.eclipse.tycho</groupId> | ||||
| 				<artifactId>tycho-source-plugin</artifactId> | ||||
| 				<version>${tycho-version}</version> | ||||
|  | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<id>plugin-source</id> | ||||
| 						<goals> | ||||
| 							<goal>plugin-source</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 			</plugin> | ||||
|  | ||||
| 			<plugin> | ||||
| 				<groupId>org.eclipse.tycho.extras</groupId> | ||||
| 				<artifactId>tycho-source-feature-plugin</artifactId> | ||||
| 				<version>${tycho-version}</version> | ||||
|  | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<id>source-feature</id> | ||||
| 						<phase>package</phase> | ||||
| 						<goals> | ||||
| 							<goal>source-feature</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
|  | ||||
| 				<configuration> | ||||
| 					<excludes> | ||||
| 						<plugin id="com.google.guava" /> | ||||
| 						<plugin id="org.hamcrest.core" /> | ||||
| 						<plugin id="org.junit" />						 | ||||
| 						<plugin id="com.minres.scviewer.e4.product" /> | ||||
| 						<plugin id="org.eclipse.core.filesystem.linux.x86_64" /> | ||||
| 						<plugin id="org.eclipse.core.filesystem.win32.x86_64" /> | ||||
| 						<plugin id="com.opcoach.e4.preferences" /> | ||||
| 					</excludes> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 			<plugin> | ||||
| 				<groupId>org.eclipse.tycho</groupId> | ||||
| 				<artifactId>tycho-p2-plugin</artifactId> | ||||
| 				<version>${tycho-version}</version> | ||||
| 				<executions> | ||||
| 					<execution> | ||||
| 						<id>attach-p2-metadata</id> | ||||
| 						<phase>package</phase> | ||||
| 						<goals> | ||||
| 							<goal>p2-metadata</goal> | ||||
| 						</goals> | ||||
| 					</execution> | ||||
| 				</executions> | ||||
| 			</plugin> | ||||
|  | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
| @@ -6,11 +6,11 @@ | ||||
| 	<parent> | ||||
| 		<groupId>com.minres.scviewer</groupId> | ||||
| 		<artifactId>com.minres.scviewer.parent</artifactId> | ||||
| 		<version>2.14.1</version> | ||||
| 		<relativePath>../../..</relativePath> | ||||
| 		<version>2.15.1</version> | ||||
| 		<relativePath>../..</relativePath> | ||||
| 	</parent> | ||||
| 	<artifactId>com.minres.scviewer.e4.product</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
|   	<version>2.15.1</version> | ||||
| 	<packaging>eclipse-repository</packaging> | ||||
| 	<groupId>com.minres.scviewer</groupId> | ||||
| 	<build> | ||||
| @@ -45,7 +45,7 @@ | ||||
| 					</formats> | ||||
| 					<products> | ||||
| 						<product> | ||||
| 							<id>product</id> | ||||
| 							<id>scviewer</id> | ||||
| 							<archiveFileName>SCViewer-${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}</archiveFileName> | ||||
| 							<rootFolders> | ||||
| 								<macosx>SCViewer.app</macosx> | ||||
|   | ||||
| @@ -1,7 +1,8 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <?pde version="3.5"?> | ||||
|  | ||||
| <product name="SCViewer" uid="product" id="com.minres.scviewer.e4.application.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" version="2.14.1" useFeatures="true" includeLaunchers="true"> | ||||
| <product name="SCViewer" uid="scviewer" id="com.minres.scviewer.e4.application.product" application="org.eclipse.e4.ui.workbench.swt.E4Application" version="2.15.1" useFeatures="true" includeLaunchers="true"> | ||||
|  | ||||
|  | ||||
|    <configIni use="default"> | ||||
|    </configIni> | ||||
| @@ -9,7 +10,7 @@ | ||||
|    <launcherArgs> | ||||
|       <programArgs>-clearPersistedState | ||||
|       </programArgs> | ||||
|       <vmArgs>-Xms64m -Xmx2G -Dosgi.instance.area=@user.home/.scviewer -Dosgi.instance.area.default=@user.home/.scviewer --add-modules=ALL-SYSTEM -Dfile.encoding=UTF-8 | ||||
|       <vmArgs>-Xms64m -Xmx4G -Dosgi.instance.area=@user.home/.scviewer -Dosgi.instance.area.default=@user.home/.scviewer --add-modules=ALL-SYSTEM -Dfile.encoding=UTF-8 | ||||
|       </vmArgs> | ||||
|       <vmArgsMac>-XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts | ||||
|       </vmArgsMac> | ||||
| @@ -17,6 +18,7 @@ | ||||
|  | ||||
|    <windowImages/> | ||||
|  | ||||
|  | ||||
|    <launcher name="scviewer"> | ||||
|       <linux icon="icons/SCViewer_512x512.xpm"/> | ||||
|       <macosx icon="icons/SCViewer.icns"/> | ||||
| @@ -33,6 +35,7 @@ | ||||
|       </win> | ||||
|    </launcher> | ||||
|  | ||||
|  | ||||
|    <vm> | ||||
|       <linux include="true">org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11</linux> | ||||
|       <macos include="true">org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11</macos> | ||||
| @@ -75,6 +78,10 @@ | ||||
|       <plugin id="org.eclipse.osgi" autoStart="true" startLevel="-1" /> | ||||
|    </configurations> | ||||
|  | ||||
|    <repositories> | ||||
|       <repository location="http://https://minres.github.io/SCViewer/repository" enabled="true" /> | ||||
|    </repositories> | ||||
|  | ||||
|    <preferencesInfo> | ||||
|       <targetfile overwrite="false"/> | ||||
|    </preferencesInfo> | ||||
|   | ||||
| @@ -12,8 +12,8 @@ | ||||
|   <parent> | ||||
|   	<groupId>com.minres.scviewer</groupId> | ||||
|   	<artifactId>com.minres.scviewer.parent</artifactId> | ||||
|   	<version>2.14.1</version> | ||||
|   	<relativePath>../../..</relativePath> | ||||
|   	<version>2.15.1</version> | ||||
|   	<relativePath>../..</relativePath> | ||||
|   </parent> | ||||
|  | ||||
|   </project> | ||||
|   | ||||
| @@ -3,3 +3,4 @@ | ||||
| /artifacts.jar | ||||
| /content.jar | ||||
| /target/ | ||||
| /gh-pages/ | ||||
|   | ||||
							
								
								
									
										104
									
								
								releng/com.minres.scviewer.updateSite/packaging-p2-composite.ant
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,104 @@ | ||||
| <?xml version="1.0"?> | ||||
| <project name="project"> | ||||
|  | ||||
|     <target name="getMajorMinorVersion"> | ||||
|         <script language="javascript"> | ||||
|             <![CDATA[ | ||||
|  | ||||
|                   // getting the value | ||||
|                   buildnumber = project.getProperty("unqualifiedVersion"); | ||||
|                   index = buildnumber.lastIndexOf("."); | ||||
|                   counter = buildnumber.substring(0, index); | ||||
|             project.setProperty("majorMinorVersion",counter); | ||||
|  | ||||
|               ]]> | ||||
|         </script> | ||||
|     </target> | ||||
|  | ||||
|     <target name="test_getMajorMinor" depends="getMajorMinorVersion"> | ||||
|         <echo message="majorMinorVersion: ${majorMinorVersion}"/> | ||||
|     </target> | ||||
|  | ||||
|     <!-- | ||||
|     site.label      The name/title/label of the created composite site | ||||
|     unqualifiedVersion  The version without any qualifier replacement | ||||
|     buildQualifier    The build qualifier | ||||
|   --> | ||||
|     <target name="compute.child.repository.data" depends="getMajorMinorVersion"> | ||||
|         <property name="full.version" value="${unqualifiedVersion}" /> | ||||
|  | ||||
|         <property name="software.download.area" location="${user.home}/p2.repositories" /> | ||||
|         <property name="updates.dir" value="updates" /> | ||||
|  | ||||
|         <property name="site.composite.name" value="${site.label} ${majorMinorVersion}" /> | ||||
|         <property name="main.site.composite.name" value="${site.label} All Versions" /> | ||||
|  | ||||
|     	<!-- | ||||
|         <property name="main.composite.repository.directory" location="${software.download.area}/${updates.dir}" /> | ||||
|       --> | ||||
|         <property name="main.composite.repository.directory" location="${software.download.area}" /> | ||||
|  | ||||
|         <property name="composite.repository.directory" value="${main.composite.repository.directory}/${majorMinorVersion}" /> | ||||
|         <property name="child.repository" value="${full.version}" /> | ||||
|         <property name="child.repository.directory" value="${composite.repository.directory}/${child.repository}/" /> | ||||
|     </target> | ||||
|  | ||||
|     <target name="p2.composite.add" depends="compute.child.repository.data"> | ||||
|         <property name="source.repository" location="${project.build.directory}/repository"/> | ||||
|  | ||||
|         <echo message=" " /> | ||||
|  | ||||
|         <echo message="Source repository path: ${source.repository}" /> | ||||
|  | ||||
|         <echo message="Copying to ${child.repository.directory}..." /> | ||||
|  | ||||
|         <mkdir dir="${child.repository.directory}"/> | ||||
|         <copy todir="${child.repository.directory}" overwrite="true"> | ||||
|             <fileset dir="${source.repository}" /> | ||||
|         </copy> | ||||
|  | ||||
|         <add.composite.repository.internal | ||||
|       composite.repository.location="${composite.repository.directory}" | ||||
|       composite.repository.name="${site.composite.name}" | ||||
|       composite.repository.child="${child.repository}" | ||||
|     /> | ||||
|  | ||||
|         <add.composite.repository.internal | ||||
|       composite.repository.location="${main.composite.repository.directory}" | ||||
|       composite.repository.name="${main.site.composite.name}" | ||||
|       composite.repository.child="${majorMinorVersion}" | ||||
|     /> | ||||
|  | ||||
|     </target> | ||||
|  | ||||
|     <!-- = = = = = = = = = = = = = = = = = | ||||
|           macrodef: add.composite.repository.internal           | ||||
|          = = = = = = = = = = = = = = = = = --> | ||||
|     <macrodef name="add.composite.repository.internal"> | ||||
|         <attribute name="composite.repository.location" /> | ||||
|         <attribute name="composite.repository.name" /> | ||||
|         <attribute name="composite.repository.child" /> | ||||
|         <sequential> | ||||
|  | ||||
|             <echo message=" " /> | ||||
|             <echo message="Composite repository       : @{composite.repository.location}" /> | ||||
|             <echo message="Composite name             : @{composite.repository.name}" /> | ||||
|             <echo message="Adding child repository    : @{composite.repository.child}" /> | ||||
|  | ||||
|             <p2.composite.repository> | ||||
|                 <repository compressed="false" location="@{composite.repository.location}" name="@{composite.repository.name}" /> | ||||
|                 <add> | ||||
|                     <repository location="@{composite.repository.child}" /> | ||||
|                 </add> | ||||
|             </p2.composite.repository> | ||||
|  | ||||
|             <echo file="@{composite.repository.location}/p2.index">version=1 | ||||
| metadata.repository.factory.order=compositeContent.xml,\! | ||||
| artifact.repository.factory.order=compositeArtifacts.xml,\! | ||||
| </echo> | ||||
|  | ||||
|         </sequential> | ||||
|     </macrodef> | ||||
|  | ||||
|  | ||||
| </project> | ||||
| @@ -7,22 +7,23 @@ | ||||
| 	<parent> | ||||
| 		<groupId>com.minres.scviewer</groupId> | ||||
| 		<artifactId>com.minres.scviewer.parent</artifactId> | ||||
| 		<version>2.14.1</version> | ||||
| 		<relativePath>../../..</relativePath> | ||||
| 		<version>2.15.1</version> | ||||
| 		<relativePath>../..</relativePath> | ||||
| 	</parent> | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <!-- make sure that zipped p2 repositories have the fully qualified version --> | ||||
|             <plugin> | ||||
|                 <groupId>org.eclipse.tycho</groupId> | ||||
|                 <artifactId>tycho-p2-repository-plugin</artifactId> | ||||
|                 <version>${tycho-version}</version> | ||||
|                 <configuration> | ||||
|                     <finalName>${project.artifactId}-${qualifiedVersion}</finalName> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<!-- make sure that zipped p2 repositories have the fully qualified version --> | ||||
| 			<plugin> | ||||
| 				<groupId>org.eclipse.tycho</groupId> | ||||
| 				<artifactId>tycho-p2-repository-plugin</artifactId> | ||||
| 				<version>${tycho-version}</version> | ||||
| 				<configuration> | ||||
| 					<finalName>${project.artifactId}-${qualifiedVersion}</finalName> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| 	 | ||||
| 	<profiles> | ||||
| 		<profile> | ||||
| 			<!-- Activate this profile to perform the release to Bintray --> | ||||
| @@ -33,38 +34,78 @@ | ||||
| 			<build> | ||||
| 				<plugins> | ||||
| 					<plugin> | ||||
| 						<groupId>com.carrotgarden.maven</groupId> | ||||
| 						<artifactId>bintray-maven-plugin</artifactId> | ||||
|     					<version>1.5.20191113165555</version> | ||||
|    						<configuration> | ||||
| 							<skip>false</skip> | ||||
| 							<!-- Bintray organization name. --> | ||||
| 							<subject>minres</subject> | ||||
| 							<!-- Bintray target repository. --> | ||||
| 							<repository>eclipse</repository> | ||||
| 							<!-- Bintray package name --> | ||||
| 							<bintrayPackage>SCViewer</bintrayPackage> | ||||
| 							<!-- Bintray package version number --> | ||||
| 							<bintrayVersion>${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}</bintrayVersion> | ||||
| 							<!-- remove any preexisting files --> | ||||
| 							<performDestroy>true</performDestroy> | ||||
| 							<!-- information used when creating the package  -->							 | ||||
| 							<packageVcsUrl>https://git.minres.com/VP-Tools/SCViewer.git</packageVcsUrl> | ||||
| 							<packageLicenses>EPL-1.0</packageLicenses> | ||||
| 							<!-- Local folder content to sync to the remote repo. --> | ||||
| 							<sourceFolder>${project.build.directory}/repository</sourceFolder> | ||||
| 							<!-- Remote folder for local content upload, relative path. --> | ||||
| 							<targetFolder>SCViewer/${parsedVersion.majorVersion}.${parsedVersion.minorVersion}</targetFolder> | ||||
| 							<!-- Bintray credentials in settings.xml. --> | ||||
| 							<serverId>bintray-minres-deploy</serverId> | ||||
| 						</configuration> | ||||
| 						<groupId>org.codehaus.mojo</groupId> | ||||
| 						<artifactId>exec-maven-plugin</artifactId> | ||||
| 						<version>3.0.0</version> | ||||
| 						<executions> | ||||
| 							<!-- Activate "bintray:upload" during "package" --> | ||||
| 							<execution> | ||||
| 								<phase>package</phase> | ||||
| 								<goals> | ||||
|                                     <goal>upload</goal> | ||||
|                                 </goals> | ||||
| 									<goal>exec</goal> | ||||
| 								</goals> | ||||
| 							</execution> | ||||
| 						</executions> | ||||
| 						<configuration> | ||||
| 							<executable>bash</executable> | ||||
| 							<!-- optional --> | ||||
| 							<workingDirectory>${software.download.area}</workingDirectory> | ||||
| 							<arguments> | ||||
| 								<argument>-c</argument> | ||||
| 								<argument>if [ -d SCViewer-GHP ]; then cd SCViewer-GHP; git pull; else git clone -v --branch gh-pages https://git.minres.com/VP-Tools/SCViewer.git SCViewer-GHP; fi</argument> | ||||
| 							</arguments> | ||||
| 							<environmentVariables> | ||||
| 								<LANG>en_US</LANG> | ||||
| 							</environmentVariables> | ||||
| 						</configuration> | ||||
| 					</plugin> | ||||
|  					<plugin> | ||||
| 						<groupId>org.eclipse.tycho.extras</groupId> | ||||
| 						<artifactId>tycho-eclipserun-plugin</artifactId> | ||||
| 						<version>${tycho-version}</version> | ||||
| 						<configuration> | ||||
| 							<!-- IMPORTANT: DO NOT split the arg line --> | ||||
| 							<appArgLine>-application org.eclipse.ant.core.antRunner -buildfile packaging-p2-composite.ant p2.composite.add -Dsite.label="SCViewer Software Repository" -Dproject.build.directory=${project.build.directory} -DunqualifiedVersion=${unqualifiedVersion} -Dsoftware.download.area="${software.download.area}/SCViewer-GHP/repository"</appArgLine> | ||||
| 							<repositories> | ||||
| 								<repository> | ||||
| 									<id>2020-03</id> | ||||
| 									<layout>p2</layout> | ||||
| 									<url>http://download.eclipse.org/releases/2020-03/</url> | ||||
| 								</repository> | ||||
| 							</repositories> | ||||
| 							<dependencies> | ||||
| 								<dependency> | ||||
| 									<artifactId>org.eclipse.ant.core</artifactId> | ||||
| 									<type>eclipse-plugin</type> | ||||
| 								</dependency> | ||||
| 								<dependency> | ||||
| 									<artifactId>org.apache.ant</artifactId> | ||||
| 									<type>eclipse-plugin</type> | ||||
| 								</dependency> | ||||
| 								<dependency> | ||||
| 									<artifactId>org.eclipse.equinox.p2.repository.tools</artifactId> | ||||
| 									<type>eclipse-plugin</type> | ||||
| 								</dependency> | ||||
| 								<dependency> | ||||
| 									<artifactId>org.eclipse.equinox.p2.core.feature</artifactId> | ||||
| 									<type>eclipse-feature</type> | ||||
| 								</dependency> | ||||
| 								<dependency> | ||||
| 									<artifactId>org.eclipse.equinox.p2.extras.feature</artifactId> | ||||
| 									<type>eclipse-feature</type> | ||||
| 								</dependency> | ||||
| 								<dependency> | ||||
| 									<artifactId>org.eclipse.equinox.ds</artifactId> | ||||
| 									<type>eclipse-plugin</type> | ||||
| 								</dependency> | ||||
| 							</dependencies> | ||||
| 						</configuration> | ||||
| 						<executions> | ||||
| 							<execution> | ||||
| 								<id>add-p2-composite-repository</id> | ||||
| 								<phase>package</phase> | ||||
| 								<goals> | ||||
| 									<goal>eclipse-run</goal> | ||||
| 								</goals> | ||||
| 							</execution> | ||||
| 						</executions> | ||||
| 					</plugin> | ||||
|   | ||||