OSDN Git Service

Improving HTML5 video controls
[android-x86/external-webkit.git] / WebKit / android / RenderSkinMediaButton.cpp
1 /*
2  * Copyright 2010, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #define LOG_TAG "WebCore"
27
28 #include "config.h"
29 #include "android_graphics.h"
30 #include "Document.h"
31 #include "IntRect.h"
32 #include "Node.h"
33 #include "RenderSkinMediaButton.h"
34 #include "SkCanvas.h"
35 #include "SkNinePatch.h"
36 #include "SkRect.h"
37 #include <utils/Debug.h>
38 #include <utils/Log.h>
39 #include <wtf/text/CString.h>
40
41 struct PatchData {
42     const char* name;
43     int8_t outset, margin;
44 };
45
46 static const PatchData gFiles[] =
47     {
48         { "btn_media_player.9.png", 0, 0 }, // DEFAULT BGD BUTTON
49         { "ic_media_pause.png", 0, 0}, // PAUSE
50         { "ic_media_play.png", 0, 0 }, // PLAY
51         { "ic_media_pause.png", 0, 0 }, // MUTE
52         { "ic_media_rew.png", 0, 0 }, // REWIND
53         { "ic_media_ff.png", 0, 0 }, // FORWARD
54         { "ic_media_fullscreen.png", 0, 0 }, // FULLSCREEN
55         { "btn_media_player_disabled.9.png", 0, 0 }, // BACKGROUND_SLIDER
56         { "scrubber_track_holo_dark.9.png", 0, 0 },  // SLIDER_TRACK
57         { "scrubber_control_holo.png", 0, 0 }      // SLIDER_THUMB
58     };
59
60 static SkBitmap gButton[sizeof(gFiles)/sizeof(gFiles[0])];
61 static bool gDecoded;
62 static bool gHighRes;
63
64 namespace WebCore {
65
66 void RenderSkinMediaButton::Init(android::AssetManager* am, String drawableDirectory)
67 {
68     static bool gInited;
69     if (gInited)
70         return;
71
72     gInited = true;
73     gDecoded = true;
74     gHighRes = drawableDirectory[drawableDirectory.length() - 5] == 'h';
75     for (size_t i = 0; i < sizeof(gFiles)/sizeof(gFiles[0]); i++) {
76         String path = drawableDirectory + gFiles[i].name;
77         if (!RenderSkinAndroid::DecodeBitmap(am, path.utf8().data(), &gButton[i])) {
78             gDecoded = false;
79             LOGD("RenderSkinButton::Init: button assets failed to decode\n\tBrowser buttons will not draw");
80             break;
81         }
82     }
83 }
84
85 void RenderSkinMediaButton::Draw(SkCanvas* canvas, const IntRect& r, int buttonType, bool translucent)
86 {
87     // If we failed to decode, do nothing.  This way the browser still works,
88     // and webkit will still draw the label and layout space for us.
89     if (!gDecoded) {
90         return;
91     }
92
93     bool drawsNinePatch = false;
94     bool drawsImage = true;
95     bool drawsBackgroundColor = true;
96
97     int ninePatchIndex = 0;
98     int imageIndex = 0;
99
100     SkRect bounds(r);
101     SkScalar imageMargin = 8;
102     SkPaint paint;
103
104     int alpha = 255;
105     if (translucent)
106         alpha = 190;
107
108     SkColor backgroundColor = SkColorSetARGB(alpha, 34, 34, 34);
109     paint.setColor(backgroundColor);
110
111     switch (buttonType) {
112     case PAUSE:
113     case PLAY:
114     case MUTE:
115     case REWIND:
116     case FORWARD:
117     case FULLSCREEN:
118     {
119          imageIndex = buttonType + 1;
120          paint.setColor(backgroundColor);
121          break;
122     }
123     case BACKGROUND_SLIDER:
124     {
125          drawsBackgroundColor = false;
126          drawsImage = false;
127          break;
128     }
129     case SLIDER_TRACK:
130     {
131          drawsNinePatch = true;
132          drawsImage = false;
133          ninePatchIndex = buttonType + 1;
134          break;
135     }
136     case SLIDER_THUMB:
137     {
138          drawsBackgroundColor = false;
139          imageMargin = 0;
140          imageIndex = buttonType + 1;
141          break;
142     }
143     default:
144          return;
145     }
146
147     if (drawsBackgroundColor) {
148         canvas->drawRect(r, paint);
149     }
150
151     if (drawsNinePatch) {
152         const PatchData& pd = gFiles[ninePatchIndex];
153         int marginValue = pd.margin + pd.outset;
154
155         SkIRect margin;
156         margin.set(marginValue, marginValue, marginValue, marginValue);
157         SkNinePatch::DrawNine(canvas, bounds, gButton[ninePatchIndex], margin);
158     }
159
160     if (drawsImage) {
161         SkScalar SIZE = gButton[imageIndex].width();
162         SkScalar width = r.width();
163         SkScalar scale = SkScalarDiv(width - 2*imageMargin, SIZE);
164         int saveScaleCount = canvas->save();
165         canvas->translate(bounds.fLeft + imageMargin, bounds.fTop + imageMargin);
166         canvas->scale(scale, scale);
167         canvas->drawBitmap(gButton[imageIndex], 0, 0, &paint);
168         canvas->restoreToCount(saveScaleCount);
169     }
170 }
171
172 } //WebCore