1 /* 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.webkit.graphics; 27 28 import java.lang.annotation.Native; 29 import java.util.HashMap; 30 import java.util.Map; 31 32 final class RenderMediaControls { 33 /** 34 * Media control part constants (types for the paintControl method) 35 */ 36 @Native private static final int PLAY_BUTTON = 1; 37 @Native private static final int PAUSE_BUTTON = 2; 38 @Native private static final int DISABLED_PLAY_BUTTON = 3; 39 40 @Native private static final int MUTE_BUTTON = 4; 41 @Native private static final int UNMUTE_BUTTON = 5; 42 @Native private static final int DISABLED_MUTE_BUTTON = 6; 43 44 //@Native private static final int FULLSCREEN_BUTTON = 7; 45 46 // background for control panel (except buttons) 47 //@Native private static final int BACKGROUND = 8; 48 49 // Time slider track is rendered by paintTimeSliderTrack 50 @Native private static final int TIME_SLIDER_TRACK = 9; 51 @Native private static final int TIME_SLIDER_THUMB = 10; 52 53 @Native private static final int VOLUME_CONTAINER = 11; 54 // Volume slider track is rendered by paintVolumeTrack 55 @Native private static final int VOLUME_TRACK = 12; 56 @Native private static final int VOLUME_THUMB = 13; 57 58 //private static final int CURRENT_TIME = 14; 59 //private static final int REMAINING_TIME = 15; 60 61 private static String getControlName(int control) { 62 switch (control) { 63 case PLAY_BUTTON: return "PLAY_BUTTON"; 64 case PAUSE_BUTTON: return "PAUSE_BUTTON"; 65 case DISABLED_PLAY_BUTTON: return "DISABLED_PLAY_BUTTON"; 66 67 case MUTE_BUTTON: return "MUTE_BUTTON"; 68 case UNMUTE_BUTTON: return "UNMUTE_BUTTON"; 69 case DISABLED_MUTE_BUTTON: return "DISABLED_MUTE_BUTTON"; 70 71 //case FULLSCREEN_BUTTON: return "FULLSCREEN_BUTTON"; 72 73 //case BACKGROUND: return "BACKGROUND"; 74 75 case TIME_SLIDER_TRACK: return "TIME_SLIDER_TRACK"; 76 case TIME_SLIDER_THUMB: return "TIME_SLIDER_THUMB"; 77 78 case VOLUME_CONTAINER: return "VOLUME_CONTAINER"; 79 case VOLUME_TRACK: return "VOLUME_TRACK"; 80 case VOLUME_THUMB: return "VOLUME_THUMB"; 81 82 //case CURRENT_TIME: return "CURRENT_TIME"; 83 //case REMAINING_TIME: return "REMAINING_TIME"; 84 } 85 return "{UNKNOWN CONTROL " + control + "}"; 86 } 87 88 89 private RenderMediaControls() {} // disable instantiations 90 91 static void paintControl(WCGraphicsContext gc, 92 int type, int x, int y, int w, int h) { 93 if (log) { 94 log("paintControl, type=" + type + "(" + getControlName(type) + ")" 95 + ", x=" + x + ", y=" + y + ", w=" + w + ", h=" + h); 96 } 97 switch (type) { 98 case PLAY_BUTTON: 99 paintControlImage("mediaPlay", gc, x, y, w, h); 100 break; 101 case PAUSE_BUTTON: 102 paintControlImage("mediaPause", gc, x, y, w, h); 103 break; 104 case DISABLED_PLAY_BUTTON: 105 paintControlImage("mediaPlayDisabled", gc, x, y, w, h); 106 break; 107 case MUTE_BUTTON: 108 paintControlImage("mediaMute", gc, x, y, w, h); 109 break; 110 case UNMUTE_BUTTON: 111 paintControlImage("mediaUnmute", gc, x, y, w, h); 112 break; 113 case DISABLED_MUTE_BUTTON: 114 paintControlImage("mediaMuteDisabled", gc, x, y, w, h); 115 break; 116 case TIME_SLIDER_THUMB: 117 paintControlImage("mediaTimeThumb", gc, x, y, w, h); 118 break; 119 case VOLUME_CONTAINER: 120 break; 121 case VOLUME_THUMB: 122 paintControlImage("mediaVolumeThumb", gc, x, y, w, h); 123 break; 124 default: 125 if (log) log("ERROR: paintControl, unknown type: " + type); 126 break; 127 } 128 } 129 130 private static final int TimeSliderTrackUnbufferedColor = 131 rgba(0xec, 0x87, 0x7d); 132 private static final int TimeSliderTrackBufferedColor = 133 rgba(0xf9, 0x1a, 0x02); 134 private static final int TimeSliderTrackThickness = 3; 135 136 static void paintTimeSliderTrack(WCGraphicsContext gc, 137 float duration, float curTime, float[] bufferedPairs, 138 int x, int y, int w, int h) { 139 if (log) { 140 String bufStr = "{"; 141 for (int i=0; i<bufferedPairs.length; i+=2) { 142 if (i>0) { 143 bufStr += ", "; 144 } 145 bufStr += "[" + bufferedPairs[i] + "-" + bufferedPairs[i+1]+"]"; 146 } 147 bufStr +="}"; 148 log("paintTimeSliderTrack, duration=" + duration 149 + ", curTime=" + curTime 150 + ", buffered=" + bufStr 151 + ", x=" + x + ", y=" + y + ", w=" + w + ", h=" + h); 152 } 153 154 // make the track height TimeSliderTrackThickness pixels 155 y += (h - TimeSliderTrackThickness)/2; 156 h = TimeSliderTrackThickness; 157 // descrease width by width of the thumb (increasing x by half of the value) 158 int thumbWidth = (fwkGetSliderThumbSize(SLIDER_TYPE_TIME) >> 16) & 0xFFFF; 159 w -= thumbWidth; 160 x += thumbWidth/2; 161 162 if (duration < 0) { 163 // the media is not available 164 } else { 165 float timeToPixel = (1f / duration) * w; 166 float start = 0f; 167 for (int i=0; i<bufferedPairs.length; i+=2) { 168 // unbuffered 169 if (log) { 170 log("..[unbuffered]: " + (x + timeToPixel*start) 171 + "-" + (x+timeToPixel * bufferedPairs[i])); 172 } 173 gc.fillRect(x + timeToPixel*start, y, 174 timeToPixel * (bufferedPairs[i] - start), h, 175 TimeSliderTrackUnbufferedColor); 176 // buffered 177 if (log) { 178 log("..[ buffered]: " + (x + timeToPixel*bufferedPairs[i]) 179 + "-" + (x+ timeToPixel * (bufferedPairs[i+1] - bufferedPairs[i]))); 180 } 181 gc.fillRect(x + timeToPixel*bufferedPairs[i], y, 182 timeToPixel * (bufferedPairs[i+1] - bufferedPairs[i]), h, 183 TimeSliderTrackBufferedColor); 184 start = bufferedPairs[i+1]; 185 } 186 if (start < duration) { 187 //last unbuffered 188 if (log) { 189 log("..[unbuffered]: " + (x + timeToPixel*start) 190 + "-" + (x+timeToPixel * duration)); 191 } 192 gc.fillRect(x + timeToPixel*start, y, 193 timeToPixel * (duration - start), h, 194 TimeSliderTrackUnbufferedColor); 195 } 196 197 } 198 } 199 200 private static final int VolumeTrackColor = rgba(0xd0, 0xd0, 0xd0, 0x80); 201 private static final int VolumeTrackThickness = 1; 202 203 static void paintVolumeTrack(WCGraphicsContext gc, 204 float curVolume, boolean muted, 205 int x, int y, int w, int h) { 206 if (log) { 207 log("paintVolumeTrack, curVolume=" + curVolume 208 + ", muted=" + (muted ? "true" : "false") 209 + ", x=" + x + ", y=" + y + ", w=" + w + ", h=" + h); 210 } 211 212 // (w+1): to shift the track 1 line righter when (w - thickness) % 2 == 1 213 x += ((w + 1) - VolumeTrackThickness)/2; 214 w = VolumeTrackThickness; 215 // descrease height by height of the thumb (increasing y by half of the value) 216 int thumbWidth = fwkGetSliderThumbSize(SLIDER_TYPE_TIME) & 0xFFFF; 217 h -= thumbWidth; 218 y += thumbWidth/2; 219 220 221 gc.fillRect(x, y, w, h, VolumeTrackColor); 222 } 223 224 private static final int SLIDER_TYPE_TIME = 0; 225 private static final int SLIDER_TYPE_VOLUME = 1; 226 /** 227 * returns ((width << 16) | height) 228 */ 229 private static int fwkGetSliderThumbSize(int type) { 230 WCImage image = null; 231 switch (type) { 232 case SLIDER_TYPE_TIME: 233 image = getControlImage("mediaTimeThumb"); 234 break; 235 case SLIDER_TYPE_VOLUME: 236 image = getControlImage("mediaVolumeThumb"); 237 break; 238 } 239 if (image != null) { 240 return (image.getWidth() << 16) | image.getHeight(); 241 } 242 return 0; 243 } 244 245 private static final Map<String, WCImage> controlImages 246 = new HashMap<String, WCImage>(); 247 248 private static WCImage getControlImage(String resName) { 249 WCImage image = controlImages.get(resName); 250 if (image == null) { 251 WCImageDecoder decoder = 252 WCGraphicsManager.getGraphicsManager().getImageDecoder(); 253 decoder.loadFromResource(resName); 254 WCImageFrame frame = decoder.getFrame(0, null); 255 if (frame != null) { 256 image = frame.getFrame(); 257 controlImages.put(resName, image); 258 } 259 } 260 return image; 261 } 262 263 private static void paintControlImage(String resName, 264 WCGraphicsContext gc, int x, int y, int w, int h) { 265 WCImage image = getControlImage(resName); 266 if (image != null) { 267 // don't stretch the image, just center it 268 x += (w - image.getWidth()) / 2; 269 w = image.getWidth(); 270 y += (h - image.getHeight()) / 2; 271 h = image.getHeight(); 272 gc.drawImage(image, 273 x, y, w, h, 274 0f, 0f, image.getWidth(), image.getHeight()); 275 } else { 276 if (log) log(" paintControlImage(" + resName + "), image is NULL"); 277 } 278 } 279 280 private static int rgba(int r, int g, int b, int a) { 281 return ((a & 0xFF) << 24) |((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF); 282 } 283 private static int rgba(int r, int g, int b) { 284 return rgba(r, g, b, 0xFF); 285 } 286 287 private final static boolean log = false; 288 private static void log(String s) { 289 System.out.println(s); 290 System.out.flush(); 291 } 292 }