* added a simple seeking slider for Marcus to play with...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17371 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-05-08 19:18:19 +00:00
parent d4ab13e6f1
commit fb36570967
7 changed files with 430 additions and 12 deletions
+9
View File
@@ -136,6 +136,7 @@ void
ControllerView::SetVolume(float value)
{
printf("ControllerView::SetVolume(%.2f)\n", value);
// 0.0 ... 1.0
}
@@ -145,3 +146,11 @@ ControllerView::ToggleMute()
printf("ControllerView::ToggleMute()\n");
}
void
ControllerView::SetPosition(float value)
{
printf("ControllerView::SetPosition(%.2f)\n", value);
// 0.0 ... 1.0
}
+1
View File
@@ -49,6 +49,7 @@ private:
virtual void SkipForward();
virtual void SetVolume(float value);
virtual void ToggleMute();
virtual void SetPosition(float value);
private:
Controller * fController;
+1
View File
@@ -14,6 +14,7 @@ Application MediaPlayer :
SoundOutput.cpp
TransportButton.cpp
TransportControlGroup.cpp
SeekSlider.cpp
VideoNode.cpp
VideoView.cpp
VolumeSlider.cpp
+314
View File
@@ -0,0 +1,314 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
*/
// NOTE: Based on my code in the BeOS interface for the VLC media player
// that I did during the VLC 0.4.3 - 0.4.6 times. Code not done by me
// removed. -Stephan Aßmus
#include "SeekSlider.h"
#include <stdio.h>
#include <string.h>
#include "DrawingTidbits.h"
#define SEEK_SLIDER_KNOB_WIDTH 8.0
const rgb_color kSeekGreen = (rgb_color){ 171, 221, 161, 255 };
const rgb_color kSeekGreenShadow = (rgb_color){ 144, 186, 136, 255 };
const rgb_color kSeekRed = (rgb_color){ 255, 0, 0, 255 };
const rgb_color kSeekRedLight = (rgb_color){ 255, 152, 152, 255 };
const rgb_color kSeekRedShadow = (rgb_color){ 178, 0, 0, 255 };
const char* kDisabledSeekMessage = "Drop files to play";
SeekSlider::SeekSlider(BRect frame, const char* name, BMessage* message,
int32 minValue, int32 maxValue)
: BControl(frame, name, NULL, message, B_FOLLOW_NONE,
B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE),
fTracking(false),
fMinValue(minValue),
fMaxValue(maxValue)
{
BFont font(be_plain_font);
font.SetSize(9.0);
SetFont(&font);
}
SeekSlider::~SeekSlider()
{
}
void
SeekSlider::AttachedToWindow()
{
BControl::AttachedToWindow();
SetViewColor(B_TRANSPARENT_32_BIT);
}
void
SeekSlider::SetValue(int32 value)
{
if (value == Value())
return;
BControl::SetValue(value);
Invoke();
}
void
SeekSlider::Draw(BRect updateRect)
{
BRect r(Bounds());
float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
float sliderStart = (r.left + knobWidth2);
float sliderEnd = (r.right - knobWidth2);
float knobPos = sliderStart
+ floorf((sliderEnd - sliderStart - 1.0) * (Value() - fMinValue)
/ (fMaxValue - fMinValue) + 0.5);
// draw both sides (the original from Be doesn't seem
// to make a difference for enabled/disabled state)
// DrawBitmapAsync(fLeftSideBits, r.LeftTop());
// DrawBitmapAsync(fRightSideBits, BPoint(sliderEnd + 1.0, r.top));
// colors for the slider area between the two bitmaps
rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color shadow = tint_color(background, B_DARKEN_2_TINT);
rgb_color softShadow = tint_color(background, B_DARKEN_1_TINT);
rgb_color darkShadow = tint_color(background, B_DARKEN_4_TINT);
rgb_color midShadow = tint_color(background, B_DARKEN_3_TINT);
rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
rgb_color softLight = tint_color(background, B_LIGHTEN_1_TINT);
rgb_color green = kSeekGreen;
rgb_color greenShadow = kSeekGreenShadow;
rgb_color black = kBlack;
rgb_color dotGrey = midShadow;
rgb_color dotGreen = greenShadow;
// draw frame
_StrokeFrame(r, softShadow, softShadow, softLight, softLight);
r.InsetBy(1.0, 1.0);
_StrokeFrame(r, black, black, light, light);
if (IsEnabled()) {
// *** enabled look ***
r.InsetBy(1.0, 1.0);
// inner shadow
_StrokeFrame(r, greenShadow, greenShadow, green, green);
r.top++;
r.left++;
_StrokeFrame(r, greenShadow, greenShadow, green, green);
// inside area
r.InsetBy(1.0, 1.0);
SetHighColor(green);
FillRect(r);
// dots
int32 dotCount = (int32)(r.Width() / 6.0);
BPoint dotPos;
dotPos.y = r.top + 2.0;
SetHighColor(dotGreen);
for (int32 i = 0; i < dotCount; i++) {
dotPos.x = sliderStart + i * 6.0 + 5.0;
StrokeLine(dotPos, BPoint(dotPos.x, dotPos.y + 6.0));
}
// slider handle
r.top -= 4.0;
r.bottom += 3.0;
r.left = knobPos - knobWidth2;
r.right = knobPos + knobWidth2;
// black outline
float handleBottomSize = 2.0;
float handleArrowSize = 6.0;
BeginLineArray(10);
// upper handle
AddLine(BPoint(r.left, r.top + handleBottomSize),
BPoint(r.left, r.top), black);
AddLine(BPoint(r.left + 1.0, r.top),
BPoint(r.right, r.top), black);
AddLine(BPoint(r.right, r.top + 1.0),
BPoint(r.right, r.top + handleBottomSize), black);
AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
BPoint(knobPos, r.top + handleArrowSize), black);
AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), black);
// lower handle
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.bottom - handleBottomSize), black);
AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
BPoint(knobPos, r.bottom - handleArrowSize), black);
AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
BPoint(r.right, r.bottom - handleBottomSize), black);
AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
BPoint(r.right, r.bottom), black);
AddLine(BPoint(r.right - 1.0, r.bottom),
BPoint(r.left + 1.0, r.bottom), black);
EndLineArray();
// inner red light and shadow lines
r.InsetBy(1.0, 1.0);
handleBottomSize--;
handleArrowSize -= 2.0;
BeginLineArray(10);
// upper handle
AddLine(BPoint(r.left, r.top + handleBottomSize),
BPoint(r.left, r.top), kSeekRedLight);
AddLine(BPoint(r.left + 1.0, r.top),
BPoint(r.right, r.top), kSeekRedLight);
AddLine(BPoint(r.right, r.top + 1.0),
BPoint(r.right, r.top + handleBottomSize), kSeekRedShadow);
AddLine(BPoint(r.right - 1.0, r.top + handleBottomSize + 1.0),
BPoint(knobPos, r.top + handleArrowSize), kSeekRedShadow);
AddLine(BPoint(knobPos - 1.0, r.top + handleArrowSize - 1.0),
BPoint(r.left + 1.0, r.top + handleBottomSize + 1.0), kSeekRedLight);
// lower handle
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.bottom - handleBottomSize), kSeekRedLight);
AddLine(BPoint(r.left + 1.0, r.bottom - handleBottomSize - 1.0),
BPoint(knobPos, r.bottom - handleArrowSize), kSeekRedLight);
AddLine(BPoint(knobPos + 1.0, r.bottom - handleArrowSize + 1.0),
BPoint(r.right, r.bottom - handleBottomSize), kSeekRedShadow);
AddLine(BPoint(r.right, r.bottom - handleBottomSize + 1.0),
BPoint(r.right, r.bottom), kSeekRedShadow);
AddLine(BPoint(r.right - 1.0, r.bottom),
BPoint(r.left + 1.0, r.bottom), kSeekRedShadow);
EndLineArray();
// fill rest of handles with red
SetHighColor(kSeekRed);
r.InsetBy(1.0, 1.0);
handleArrowSize -= 2.0;
BPoint arrow[3];
// upper handle arrow
arrow[0].x = r.left;
arrow[0].y = r.top;
arrow[1].x = r.right;
arrow[1].y = r.top;
arrow[2].x = knobPos;
arrow[2].y = r.top + handleArrowSize;
FillPolygon(arrow, 3);
// lower handle arrow
arrow[0].x = r.left;
arrow[0].y = r.bottom;
arrow[1].x = r.right;
arrow[1].y = r.bottom;
arrow[2].x = knobPos;
arrow[2].y = r.bottom - handleArrowSize;
FillPolygon(arrow, 3);
} else {
// *** disabled look ***
r.InsetBy(1.0, 1.0);
_StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
r.InsetBy(1.0, 1.0);
_StrokeFrame(r, darkShadow, darkShadow, darkShadow, darkShadow);
r.InsetBy(1.0, 1.0);
SetHighColor(darkShadow);
SetLowColor(shadow);
// stripes
float width = floorf(StringWidth(kDisabledSeekMessage));
float textPos = r.left + r.Width() / 2.0 - width / 2.0;
pattern stripes = { { 0xc7, 0x8f, 0x1f, 0x3e, 0x7c, 0xf8, 0xf1, 0xe3 } };
BRect stripesRect(r);
stripesRect.right = textPos - 5.0;
FillRect(stripesRect, stripes);
stripesRect.left = textPos + width + 3.0;
stripesRect.right = r.right;
FillRect(stripesRect, stripes);
// info text
r.left = textPos - 4.0;
r.right = textPos + width + 2.0;
FillRect(r);
SetHighColor(shadow);
SetLowColor(darkShadow);
font_height fh;
GetFontHeight(&fh);
DrawString(kDisabledSeekMessage, BPoint(textPos, r.top + ceilf(fh.ascent) - 1.0));
}
}
void
SeekSlider::MouseDown(BPoint where)
{
if (IsEnabled() && Bounds().Contains(where)) {
SetValue(_ValueFor(where.x));
fTracking = true;
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
}
}
void
SeekSlider::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
{
if (fTracking) {
SetValue(_ValueFor(where.x));
}
}
void
SeekSlider::MouseUp(BPoint where)
{
if (fTracking) {
fTracking = false;
}
}
void
SeekSlider::ResizeToPreferred()
{
float width = 15.0 + StringWidth(kDisabledSeekMessage) + 15.0;
ResizeTo(width, 17.0);
}
void
SeekSlider::SetPosition(float position)
{
SetValue(fMinValue + (int32)floorf((fMaxValue - fMinValue) * position + 0.5));
}
// #pragma mark -
int32
SeekSlider::_ValueFor(float xPos) const
{
BRect r(Bounds());
float knobWidth2 = SEEK_SLIDER_KNOB_WIDTH / 2.0;
float sliderStart = (r.left + knobWidth2);
float sliderEnd = (r.right - knobWidth2);
int32 value = fMinValue + (int32)(((xPos - sliderStart) * (fMaxValue - fMinValue))
/ (sliderEnd - sliderStart - 1.0));
if (value < fMinValue)
value = fMinValue;
if (value > fMaxValue)
value = fMaxValue;
return value;
}
void
SeekSlider::_StrokeFrame(BRect r, rgb_color left, rgb_color top,
rgb_color right, rgb_color bottom)
{
BeginLineArray(4);
AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), left);
AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), top);
AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), right);
AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), bottom);
EndLineArray();
}
+52
View File
@@ -0,0 +1,52 @@
/*
* Copyright 2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* Stephan Aßmus <[email protected]>
*/
#ifndef SEEK_SLIDER_H
#define SEEK_SLIDER_H
#include <Box.h>
#include <Control.h>
class SeekSlider : public BControl {
public:
SeekSlider(BRect frame,
const char* name,
BMessage* message,
int32 minValue,
int32 maxValue);
virtual ~SeekSlider();
// BControl interface
virtual void AttachedToWindow();
virtual void SetValue(int32 value);
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
virtual void MouseUp(BPoint where);
virtual void ResizeToPreferred();
// SeekSlider
void SetPosition(float position);
private:
int32 _ValueFor(float x) const;
void _StrokeFrame(BRect frame,
rgb_color left,
rgb_color top,
rgb_color right,
rgb_color bottom);
bool fTracking;
int32 fMinValue;
int32 fMaxValue;
};
#endif //SEEK_SLIDER_H
+48 -12
View File
@@ -19,9 +19,11 @@
#include "ButtonBitmaps.h"
#include "TransportButton.h"
#include "SeekSlider.h"
#include "VolumeSlider.h"
enum {
MSG_SEEK = 'seek',
MSG_PLAY = 'play',
MSG_STOP = 'stop',
MSG_REWIND = 'rwnd',
@@ -38,6 +40,9 @@ enum {
#define VOLUME_MIN_WIDTH 70.0
#define VOLUME_SLIDER_LAYOUT_WEIGHT 2.0
#define kMaxVolume 1024
#define kMaxSeekPos 65535
// constructor
TransportControlGroup::TransportControlGroup(BRect frame)
: BView(frame, "transport control group",
@@ -48,7 +53,14 @@ TransportControlGroup::TransportControlGroup(BRect frame)
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BRect frame(0.0, 0.0, 10.0, 10.0);
// Seek Slider
fSeekSlider = new SeekSlider(frame, "seek slider",
new BMessage(MSG_SEEK),
0, kMaxSeekPos);
fSeekSlider->ResizeToPreferred();
AddChild(fSeekSlider);
// Buttons
// Skip Back
frame.right = kRewindBitmapWidth - 1;
@@ -130,7 +142,7 @@ TransportControlGroup::TransportControlGroup(BRect frame)
// Volume Slider
fVolumeSlider = new VolumeSlider(BRect(0.0, 0.0, VOLUME_MIN_WIDTH,
kVolumeSliderBitmapHeight - 1.0),
"volume slider", 0, 255,
"volume slider", 0, kMaxVolume,
new BMessage(MSG_SET_VOLUME));
fVolumeSlider->SetValue(128);
AddChild(fVolumeSlider);
@@ -148,6 +160,7 @@ TransportControlGroup::AttachedToWindow()
SetEnabled(EnabledButtons());
// we are now a valid BHandler
fSeekSlider->SetTarget(this);
fVolumeSlider->SetTarget(this);
fSkipBack->SetTarget(this);
fSkipForward->SetTarget(this);
@@ -215,27 +228,38 @@ TransportControlGroup::MessageReceived(BMessage* message)
_ToggleMute();
break;
case MSG_SEEK:
_UpdatePosition();
break;
default:
BView::MessageReceived(message);
break;
}
}
// #pragma mark -
// default implementation for the virtuals
uint32 TransportControlGroup::EnabledButtons() { return 0; }
void TransportControlGroup::TogglePlaying() {}
void TransportControlGroup::Stop() {}
void TransportControlGroup::Rewind() {}
void TransportControlGroup::Forward() {}
void TransportControlGroup::SkipBackward() {}
void TransportControlGroup::SkipForward() {}
void TransportControlGroup::SetVolume(float value) {}
void TransportControlGroup::ToggleMute() {}
uint32 TransportControlGroup::EnabledButtons() { return 0; }
void TransportControlGroup::TogglePlaying() {}
void TransportControlGroup::Stop() {}
void TransportControlGroup::Rewind() {}
void TransportControlGroup::Forward() {}
void TransportControlGroup::SkipBackward() {}
void TransportControlGroup::SkipForward() {}
void TransportControlGroup::SetVolume(float value) {}
void TransportControlGroup::ToggleMute() {}
void TransportControlGroup::SetPosition(float value) {}
// #pragma mark -
// SetEnabled
void
TransportControlGroup::SetEnabled(uint32 buttons)
{
fSeekSlider->SetEnabled(buttons & SEEK_ENABLED);
fVolumeSlider->SetEnabled(buttons & VOLUME_ENABLED);
fMute->SetEnabled(buttons & VOLUME_ENABLED);
@@ -316,13 +340,17 @@ TransportControlGroup::_LayoutControls(BRect frame) const
minWidth += fMute->Bounds().Width();
minWidth += VOLUME_MIN_WIDTH;
// layout seek slider
r.bottom = r.top + fSeekSlider->Bounds().Height();
_LayoutControl(fSeekSlider, r, true);
float currentWidth = frame.Width();
float space = (currentWidth - minWidth) / 6.0;
// apply weighting
space = MIN_SPACE + (space - MIN_SPACE) / VOLUME_SLIDER_LAYOUT_WEIGHT;
// layout controls with "space" inbetween
r.left = frame.left;
r.top = r.top + MIN_SPACE;
r.top = r.bottom + MIN_SPACE + 1.0;
r.bottom = frame.bottom;
// skip back
r.right = r.left + fSkipBack->Bounds().Width();
@@ -375,6 +403,7 @@ TransportControlGroup::_MinFrame() const
// add up height of seek slider and heighest control on bottom
float minHeight = 2 * BORDER_INSET;
minHeight += fSeekSlider->Bounds().Height() + MIN_SPACE + MIN_SPACE / 2.0;
minHeight += fBottomControlHeight;
return BRect(0.0, 0.0, minWidth - 1.0, minHeight - 1.0);
}
@@ -455,4 +484,11 @@ TransportControlGroup::_ToggleMute()
ToggleMute();
}
// _UpdatePosition
void
TransportControlGroup::_UpdatePosition()
{
SetPosition((float)(fSeekSlider->Value() / (float)kMaxSeekPos));
}
@@ -17,6 +17,7 @@
class PlayPauseButton;
class TransportButton;
class SeekSlider;
class VolumeSlider;
enum {
@@ -32,6 +33,7 @@ enum {
SEEK_FORWARD_ENABLED = 1 << 3,
SKIP_FORWARD_ENABLED = 1 << 4,
VOLUME_ENABLED = 1 << 5,
SEEK_ENABLED = 1 << 6,
};
class TransportControlGroup : public BView {
@@ -55,6 +57,7 @@ class TransportControlGroup : public BView {
virtual void SkipForward();
virtual void SetVolume(float value);
virtual void ToggleMute();
virtual void SetPosition(float value);
void SetEnabled(uint32 whichButtons);
@@ -82,7 +85,9 @@ class TransportControlGroup : public BView {
void _SkipForward();
void _SetVolume();
void _ToggleMute();
void _UpdatePosition();
SeekSlider* fSeekSlider;
VolumeSlider* fVolumeSlider;