📄 timelineviewer.java
字号:
y + ((height * 3) / 4)); g2d.setStroke(stroke); } } /** * Paints the tag is edited by dragging its boundaries, or by dragging the * whole tag. * * @param g2d * @param x * @param y * @param width * @param height */ private void paintDragEditTag2D(Graphics2D g2d, int x, int y, int width, int height) { g2d.setColor(dragEditColor); if (aaStrokeBold) { g2d.setStroke(stroke2); } int top = 0; int bottom = height; g2d.drawLine(x, y + top, x, y + bottom); top = height / 2; if (aaStrokeBold) { top++; } //g2d.drawLine(x, y + top + 1, x + width, y + top + 1); g2d.drawLine(x, y + top, x + width, y + top); g2d.drawLine(x + width, y, x + width, y + bottom); g2d.setStroke(stroke); } /** * Paint empty slots on this tier.<br> * Iterate over the parent tags in the visible area and paint a tag when * it is not on the child. * * @param g2d the graphics context * @param ti the tier containing empty slots * @param y y coordinate for the tags * @param he height of the tags */ private void paintEmptySlots(Graphics2D g2d, TierImpl ti, int y, int he) { try { TierImpl parent = (TierImpl) ti.getParentTier(); Vector tags = parent.getAnnotations(); Annotation a; int x; int wi; Iterator tagIt = tags.iterator(); while (tagIt.hasNext()) { a = (Annotation) tagIt.next(); if (a.getEndTimeBoundary() < intervalBeginTime) { continue; } if (a.getBeginTimeBoundary() > intervalEndTime) { break; } if (a.getChildrenOnTier(ti).size() == 0) { x = (int) ((a.getBeginTimeBoundary() / msPerPixel) - (intervalBeginTime / msPerPixel)); wi = (int) ((a.getEndTimeBoundary() - a.getBeginTimeBoundary()) / msPerPixel); g2d.setColor(Constants.SHAREDCOLOR4); g2d.fillRect(x, y, wi, he); g2d.setColor(Constants.DEFAULTFOREGROUNDCOLOR); g2d.drawRect(x, y, wi, he); } } } catch (Exception ex) { ex.printStackTrace(); } } /** * Returns the x-ccordinate for a specific time. The coordinate is in the * component's coordinate system. * * @param t time * * @return int the x-coordinate for the specified time */ public int xAt(long t) { return (int) ((t - intervalBeginTime) / msPerPixel); } /** * Returns the time in ms at a given position in the current image. The * given x coordinate is in the component's ("this") coordinate system. * The interval begin time is included in the calculation of the time at * the given coordinate. * * @param x x-coordinate * * @return the mediatime corresponding to the specified position */ public long timeAt(int x) { return intervalBeginTime + (x * msPerPixel); } /** * Calculates the x coordinate in virtual image space.<br> * This virtual image would be an image of width <br> * media duration in ms / ms per pixel. Therefore the return value does * not correct for interval begin time and is not necessarily within the * bounds of this component. * * @param theTime the media time * * @return the x coordinate in the virtual image space */ private int timeToPixels(long theTime) { return (int) theTime / msPerPixel; } /** * Calculates the time corresponding to a pixel location in the virtual * image space. * * @param x the x coordinate in virtual image space * * @return the media time at the specified point */ private long pixelToTime(int x) { return (long) (x * msPerPixel); } /** * Implements updateTimeScale from TimeScaleBasedViewer to adjust the * TimeScale if needed and when in TimeScale connected mode.<br> * Checks the GlobalTimeScaleIntervalBeginTime and * GlobalTimeScaleMsPerPixel and adjusts the interval and resolution of * this viewer when they differ from the global values.<br> * For the time being assume that the viewer is notified only once when * the resolution or the interval begintime has changed. */ public void updateTimeScale() { if (timeScaleConnected) { //if the resolution is changed recalculate the begin time if (getGlobalTimeScaleMsPerPixel() != msPerPixel) { setLocalTimeScaleMsPerPixel(getGlobalTimeScaleMsPerPixel()); } else if (getGlobalTimeScaleIntervalBeginTime() != intervalBeginTime) { //assume the resolution has not been changed setLocalTimeScaleIntervalBeginTime(getGlobalTimeScaleIntervalBeginTime()); //System.out.println("update begin time in TimeLineViewer called"); } } } /** * Sets whether or not this viewer listens to global time scale updates. * * @param connected the new timescale connected value */ public void setTimeScaleConnected(boolean connected) { timeScaleConnected = connected; if (timeScaleConnected) { if (msPerPixel != getGlobalTimeScaleMsPerPixel()) { setLocalTimeScaleMsPerPixel(getGlobalTimeScaleMsPerPixel()); } if (intervalBeginTime != getGlobalTimeScaleIntervalBeginTime()) { setLocalTimeScaleIntervalBeginTime(getGlobalTimeScaleIntervalBeginTime()); } } } /** * Gets whether this viewer listens to time scale updates from other * viewers. * * @return true when connected to global time scale values, false otherwise */ public boolean getTimeScaleConnected() { return timeScaleConnected; } /** * Checks whether this viewer is TimeScale connected and changes the * milliseconds per pixel value globally or locally. * * @param mspp the new milliseconds per pixel value */ public void setMsPerPixel(int mspp) { if (timeScaleConnected) { setGlobalTimeScaleMsPerPixel(mspp); setGlobalTimeScaleIntervalBeginTime(intervalBeginTime); setGlobalTimeScaleIntervalEndTime(intervalEndTime); } else { setLocalTimeScaleMsPerPixel(mspp); } } /** * Change the horizontal resolution or zoomlevel locally. The msPerPixel * denotes the number of milliseconds of which the sound samples should be * merged to one value. It corresponds to one pixel in image space (a * pixel is the smallest unit in image space).<br> * The position on the screen of crosshair cursor should change as little * as possible.<br> * This is calculated as follows:<br> * The absolute x coordinate in image space is the current media time * divided by the new msPerPixel.<br> * <pre> * |----------|----------|-------x--|-- <br> * |imagesize | | absolute x coordinate of media time<br> * | 1 | 2 | 3 | * </pre> * Calculate the number of screen images that fit within the absolute x * coordinate. The new position on the screen would then be the absolute x * coordinate minus the number of screen images multiplied by the image * width. The difference between the old x value and the new x value is * then used to calculte the new interval start time.<br> * The new start time = (number of screen images image width - * difference) msPerPixel. * * @param step the new horizontal zoomlevel */ private void setLocalTimeScaleMsPerPixel(int step) { if (msPerPixel == step) { return; } if (step >= 1) { msPerPixel = step; } else { msPerPixel = 1; } resolution = (int) (1000f / msPerPixel); /*stop the player if necessary*/ boolean playing = playerIsPlaying(); if (playing) { stopPlayer(); } long mediaTime = getMediaTime(); int oldScreenPos = crossHairPos; int newMediaX = (int) (mediaTime / msPerPixel); int numScreens; if (imageWidth > 0) { numScreens = (int) (mediaTime / (imageWidth * msPerPixel)); } else { numScreens = 0; } int newScreenPos = newMediaX - (numScreens * imageWidth); int diff = oldScreenPos - newScreenPos; //new values intervalBeginTime = ((numScreens * imageWidth) - diff) * msPerPixel; if (intervalBeginTime < 0) { intervalBeginTime = 0; } intervalEndTime = intervalBeginTime + (imageWidth * msPerPixel); recalculateTagSizes(); crossHairPos = xAt(mediaTime); selectionBeginPos = xAt(getSelectionBeginTime()); selectionEndPos = xAt(getSelectionEndTime()); updateHorScrollBar(); paintBuffer(); if (playing) { startPlayer(); } int zoom = (int) (100f * (10f / msPerPixel)); if (zoom <= 0) { zoom = 100; } updateZoomPopup(zoom); //repaint(); } /** * Returns the current msPerPixel. * * @return msPerPixel */ public int getMsPerPixel() { return msPerPixel; } /** * Calls #setMsPerPixel with the appropriate value. In setMsPerPixel the * value of this.resolution is actually set. msPerPixel = 1000 / resolution<br> * resolution = 1000 / msPerPixel * * @param resolution the new resolution */ public void setResolution(int resolution) { if (resolution < 1) { this.resolution = 1; } else { this.resolution = resolution; } int mspp = (int) (1000f / resolution); setMsPerPixel(mspp); } /** * Sets the resolution by providing a factor the default PIXELS_FOR_SECOND * should be multiplied with.<br> * resolution = factor PIXELS_FOR_SECOND.<br> * <b>Note:</b><br> * The factor = 100 / resolution_menu_percentage ! * * @param factor the multiplication factor */ public void setResolutionFactor(float factor) { int res = (int) (PIXELS_FOR_SECOND * factor); setResolution(res); } /** * Gets the current resolution * * @return the current resolution */ public int getResolution() { return resolution; } /** * Find the tag at the given location. * * @param p the location * @param tierIndex the tier the tag should be found in * * @return the tag */ private Tag2D getTagAt(Point2D p, int tierIndex) { if ((tierIndex < 0) || (tierIndex > (visibleTiers.size() - 1))) { return null; } long pTime = pixelToTime((int) p.getX()); Tag2D t2d; Iterator it = ((Tier2D) visibleTiers.get(tierIndex)).getTags(); while (it.hasNext()) { t2d = (Tag2D) it.next(); if ((pTime >= t2d.getBeginTime()) && (pTime <= t2d.getEndTime())) { return t2d; } } return null; } /** * Calculate the index in the visible tiers array for the given y * coordinate. * * @param p DOCUMENT ME! * * @return the index of the Tier2D or -1 when not found */ private int getTierIndexForPoint(Point2D p) { int y = (int) p.getY() - rulerHeight; if ((y < 0) || (y > (visibleTiers.size() * pixelsForTierHeight))) { return -1; } else { return y / pixelsForTierHeight; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -