xref: /haiku/src/apps/soundrecorder/TrackSlider.cpp (revision 425ac1b60a56f4df7a0e88bd784545c0ec4fa01f)
157e2f323SJérôme Duval /*
257e2f323SJérôme Duval  * Copyright 2005, Jérôme Duval. All rights reserved.
357e2f323SJérôme Duval  * Distributed under the terms of the MIT License.
457e2f323SJérôme Duval  *
53ee96407SJérôme Duval  * Inspired by SoundCapture from Be newsletter (Media Kit Basics: Consumers
63ee96407SJérôme Duval  * and Producers)
757e2f323SJérôme Duval  */
857e2f323SJérôme Duval 
957e2f323SJérôme Duval #include <stdio.h>
10758b1d0eSIngo Weinhold #include <string.h>
1142f70a5dSJérôme Duval #include <Screen.h>
1257e2f323SJérôme Duval 
1357e2f323SJérôme Duval #include "TrackSlider.h"
1457e2f323SJérôme Duval #include "icon_button.h"
1557e2f323SJérôme Duval 
TrackSlider(BRect rect,const char * title,BMessage * msg,uint32 resizeFlags)163ee96407SJérôme Duval TrackSlider::TrackSlider(BRect rect, const char *title, BMessage *msg,
173ee96407SJérôme Duval 	uint32 resizeFlags)
183ee96407SJérôme Duval 	:
193ee96407SJérôme Duval 	BControl(rect, "slider", NULL, msg, resizeFlags, B_WILL_DRAW
203ee96407SJérôme Duval 		| B_FRAME_EVENTS),
213ee96407SJérôme Duval 	fLeftTime(0),
223ee96407SJérôme Duval 	fRightTime(1000000),
233ee96407SJérôme Duval 	fMainTime(0),
243ee96407SJérôme Duval 	fTotalTime(1000000),
253ee96407SJérôme Duval 	fLeftTracking(false),
263ee96407SJérôme Duval 	fRightTracking(false),
273ee96407SJérôme Duval 	fMainTracking(false),
283ee96407SJérôme Duval 	fBitmap(NULL),
293ee96407SJérôme Duval 	fBitmapView(NULL)
3057e2f323SJérôme Duval {
3157e2f323SJérôme Duval 	fFont.SetSize(8.0);
3257e2f323SJérôme Duval 	fFont.SetFlags(B_DISABLE_ANTIALIASING);
3357e2f323SJérôme Duval 
3457e2f323SJérôme Duval 	int32 numFamilies = count_font_families();
3557e2f323SJérôme Duval 	for (int32 i = 0; i < numFamilies; i++ ) {
3657e2f323SJérôme Duval 		font_family family;
3757e2f323SJérôme Duval 		uint32 flags;
3857e2f323SJérôme Duval 		if ((get_font_family(i, &family, &flags) == B_OK)
3957e2f323SJérôme Duval 			&& (strcmp(family, "Baskerville") == 0)) {
4057e2f323SJérôme Duval 			fFont.SetFamilyAndFace(family, B_REGULAR_FACE);
4157e2f323SJérôme Duval 			break;
4257e2f323SJérôme Duval 		}
4357e2f323SJérôme Duval 	}
4457e2f323SJérôme Duval 
4557e2f323SJérôme Duval }
4657e2f323SJérôme Duval 
4757e2f323SJérôme Duval 
~TrackSlider()4857e2f323SJérôme Duval TrackSlider::~TrackSlider()
4957e2f323SJérôme Duval {
5042f70a5dSJérôme Duval 	delete fBitmap;
5157e2f323SJérôme Duval }
5257e2f323SJérôme Duval 
5357e2f323SJérôme Duval 
5457e2f323SJérôme Duval void
AttachedToWindow()5557e2f323SJérôme Duval TrackSlider::AttachedToWindow()
5657e2f323SJérôme Duval {
5757e2f323SJérôme Duval 	BControl::AttachedToWindow();
5857e2f323SJérôme Duval 	SetViewColor(B_TRANSPARENT_COLOR);
59ad0c65eaSJérôme Duval 	_InitBitmap();
60ad0c65eaSJérôme Duval 	_RenderBitmap();
6157e2f323SJérôme Duval }
6257e2f323SJérôme Duval 
6357e2f323SJérôme Duval 
6442f70a5dSJérôme Duval void
_InitBitmap()65ad0c65eaSJérôme Duval TrackSlider::_InitBitmap()
6642f70a5dSJérôme Duval {
67f67a6779SMurai Takashi 	if (fBitmap != NULL) {
68f67a6779SMurai Takashi 		if (fBitmapView != NULL) {
6942f70a5dSJérôme Duval 			fBitmap->RemoveChild(fBitmapView);
7042f70a5dSJérôme Duval 			delete fBitmapView;
7142f70a5dSJérôme Duval 		}
7242f70a5dSJérôme Duval 		delete fBitmap;
73f67a6779SMurai Takashi 	}
7442f70a5dSJérôme Duval 
7542f70a5dSJérôme Duval 	BRect rect = Bounds();
7642f70a5dSJérôme Duval 
7742f70a5dSJérôme Duval 	fBitmap = new BBitmap(rect, BScreen().ColorSpace(), true);
7842f70a5dSJérôme Duval 
794c9da6dcSStephan Aßmus 	fBitmapView = new SliderOffscreenView(rect.OffsetToSelf(B_ORIGIN), "bitmapView");
8042f70a5dSJérôme Duval 	fBitmap->AddChild(fBitmapView);
8142f70a5dSJérôme Duval 
8242f70a5dSJérôme Duval 	fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth;
8342f70a5dSJérôme Duval 	if (fTotalTime == 0) {
8442f70a5dSJérôme Duval 		fBitmapView->fLeftX = 14;
8542f70a5dSJérôme Duval 		fBitmapView->fRightX = fBitmapView->fRight;
8642f70a5dSJérôme Duval 		fBitmapView->fPositionX = 15;
8742f70a5dSJérôme Duval 	} else {
883ee96407SJérôme Duval 		fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15)
893ee96407SJérôme Duval 			* ((double)fLeftTime / fTotalTime);
903ee96407SJérôme Duval 		fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16)
913ee96407SJérôme Duval 			* ((double)fRightTime / fTotalTime);
923ee96407SJérôme Duval 		fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14)
933ee96407SJérôme Duval 			* ((double)fMainTime / fTotalTime);
9442f70a5dSJérôme Duval 	}
9542f70a5dSJérôme Duval }
9642f70a5dSJérôme Duval 
9757e2f323SJérôme Duval #define SLIDER_BASE 10
9857e2f323SJérôme Duval 
9957e2f323SJérôme Duval void
_RenderBitmap()100ad0c65eaSJérôme Duval TrackSlider::_RenderBitmap()
10142f70a5dSJérôme Duval {
10242f70a5dSJérôme Duval 	/* rendering */
10342f70a5dSJérôme Duval 	if (fBitmap->Lock()) {
10442f70a5dSJérôme Duval 		fBitmapView->DrawX();
10542f70a5dSJérôme Duval 		fBitmap->Unlock();
10642f70a5dSJérôme Duval 	}
10742f70a5dSJérôme Duval }
10842f70a5dSJérôme Duval 
10942f70a5dSJérôme Duval 
11042f70a5dSJérôme Duval void
Draw(BRect updateRect)11157e2f323SJérôme Duval TrackSlider::Draw(BRect updateRect)
11257e2f323SJérôme Duval {
11342f70a5dSJérôme Duval 	DrawBitmapAsync(fBitmap, BPoint(0,0));
11442f70a5dSJérôme Duval 
115ad0c65eaSJérôme Duval 	_DrawCounter(fMainTime, fBitmapView->fPositionX, fMainTracking);
11642f70a5dSJérôme Duval 	if (fLeftTracking)
117ad0c65eaSJérôme Duval 		_DrawCounter(fLeftTime, fBitmapView->fLeftX, fLeftTracking);
11842f70a5dSJérôme Duval 	else if (fRightTracking)
119ad0c65eaSJérôme Duval 		_DrawCounter(fRightTime, fBitmapView->fRightX, fRightTracking);
12042f70a5dSJérôme Duval 
121ad0c65eaSJérôme Duval 	_DrawMarker(fBitmapView->fPositionX);
12242f70a5dSJérôme Duval 
12342f70a5dSJérôme Duval 	Sync();
12442f70a5dSJérôme Duval }
12542f70a5dSJérôme Duval 
12642f70a5dSJérôme Duval 
12742f70a5dSJérôme Duval void
_DrawCounter(bigtime_t timestamp,float position,bool isTracking)128ad0c65eaSJérôme Duval TrackSlider::_DrawCounter(bigtime_t timestamp, float position, bool isTracking)
12942f70a5dSJérôme Duval {
13042f70a5dSJérôme Duval 	// timecounter
13142f70a5dSJérôme Duval 
13242f70a5dSJérôme Duval 	rgb_color gray = {128,128,128};
13342f70a5dSJérôme Duval 	rgb_color blue = {0,0,140};
13442f70a5dSJérôme Duval 	rgb_color blue2 = {146,146,214};
13542f70a5dSJérôme Duval 	rgb_color white = {255,255,255};
13642f70a5dSJérôme Duval 
13742f70a5dSJérôme Duval 	char string[12];
138ad0c65eaSJérôme Duval 	_TimeToString(timestamp, string);
13942f70a5dSJérôme Duval 	int32 halfwidth = ((int32)fFont.StringWidth(string)) / 2;
14042f70a5dSJérôme Duval 
14142f70a5dSJérôme Duval 	float counterX = position;
14242f70a5dSJérôme Duval 	if (counterX < 39)
14342f70a5dSJérôme Duval 		counterX = 39;
14442f70a5dSJérôme Duval 	if (counterX > fBitmapView->fRight - 23)
14542f70a5dSJérôme Duval 		counterX = fBitmapView->fRight - 23;
14642f70a5dSJérôme Duval 
14742f70a5dSJérôme Duval 	BeginLineArray(4);
14842f70a5dSJérôme Duval 	if (!isTracking) {
1493ee96407SJérôme Duval 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1),
1503ee96407SJérôme Duval 			BPoint(counterX+halfwidth+3,SLIDER_BASE+1), gray);
1513ee96407SJérôme Duval 		AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1),
1523ee96407SJérôme Duval 			BPoint(counterX+halfwidth+4,SLIDER_BASE-8), gray);
1533ee96407SJérôme Duval 		AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1),
1543ee96407SJérôme Duval 			BPoint(counterX-halfwidth-4,SLIDER_BASE-9), white);
1553ee96407SJérôme Duval 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9),
1563ee96407SJérôme Duval 			BPoint(counterX+halfwidth+4,SLIDER_BASE-9), white);
15742f70a5dSJérôme Duval 		SetHighColor(216,216,216);
15842f70a5dSJérôme Duval 	} else {
1593ee96407SJérôme Duval 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE+1),
1603ee96407SJérôme Duval 			BPoint(counterX+halfwidth+3,SLIDER_BASE+1), blue);
1613ee96407SJérôme Duval 		AddLine(BPoint(counterX+halfwidth+4,SLIDER_BASE+1),
1623ee96407SJérôme Duval 			BPoint(counterX+halfwidth+4,SLIDER_BASE-9), blue2);
1633ee96407SJérôme Duval 		AddLine(BPoint(counterX-halfwidth-4,SLIDER_BASE+1),
1643ee96407SJérôme Duval 			BPoint(counterX-halfwidth-4,SLIDER_BASE-9), blue2);
1653ee96407SJérôme Duval 		AddLine(BPoint(counterX-halfwidth-3,SLIDER_BASE-9),
1663ee96407SJérôme Duval 			BPoint(counterX+halfwidth+3,SLIDER_BASE-9), blue2);
16742f70a5dSJérôme Duval 		SetHighColor(48,48,241);
16842f70a5dSJérôme Duval 	}
16942f70a5dSJérôme Duval 	EndLineArray();
1703ee96407SJérôme Duval 	FillRect(BRect(counterX-halfwidth-3,SLIDER_BASE-8,counterX+halfwidth+3,
1713ee96407SJérôme Duval 		SLIDER_BASE));
17242f70a5dSJérôme Duval 
17342ee4863SJérôme Duval #ifdef __HAIKU__
17442ee4863SJérôme Duval 	SetDrawingMode(B_OP_OVER);
17542ee4863SJérôme Duval #else
17642f70a5dSJérôme Duval 	SetDrawingMode(B_OP_COPY);
17742ee4863SJérôme Duval #endif
17842f70a5dSJérôme Duval 	if (isTracking)
17942f70a5dSJérôme Duval 		SetHighColor(255,255,255);
18042f70a5dSJérôme Duval 	else
18142f70a5dSJérôme Duval 		SetHighColor(0,0,0);
18242f70a5dSJérôme Duval 	SetLowColor(ViewColor());
18342f70a5dSJérôme Duval 
18442f70a5dSJérôme Duval 	SetFont(&fFont);
18542f70a5dSJérôme Duval 	DrawString(string, BPoint(counterX-halfwidth, SLIDER_BASE-1));
18642f70a5dSJérôme Duval 
18742f70a5dSJérôme Duval }
18842f70a5dSJérôme Duval 
18942f70a5dSJérôme Duval 
19042f70a5dSJérôme Duval void
_DrawMarker(float position)191ad0c65eaSJérôme Duval TrackSlider::_DrawMarker(float position)
19242f70a5dSJérôme Duval {
19342f70a5dSJérôme Duval 	rgb_color black = {0,0,0};
19442f70a5dSJérôme Duval 	rgb_color rose = {255,152,152};
19542f70a5dSJérôme Duval 	rgb_color red = {255,0,0};
19642f70a5dSJérôme Duval 	rgb_color bordeau = {178,0,0};
19742f70a5dSJérôme Duval 	rgb_color white = {255,255,255};
19842f70a5dSJérôme Duval 
19942f70a5dSJérôme Duval 	BeginLineArray(30);
2003ee96407SJérôme Duval 	AddLine(BPoint(position,SLIDER_BASE+7), BPoint(position-4,SLIDER_BASE+3),
2013ee96407SJérôme Duval 		black);
2023ee96407SJérôme Duval 	AddLine(BPoint(position-4,SLIDER_BASE+3), BPoint(position-4,SLIDER_BASE+1),
2033ee96407SJérôme Duval 		black);
2043ee96407SJérôme Duval 	AddLine(BPoint(position-4,SLIDER_BASE+1), BPoint(position+4,SLIDER_BASE+1),
2053ee96407SJérôme Duval 		black);
2063ee96407SJérôme Duval 	AddLine(BPoint(position+4,SLIDER_BASE+1), BPoint(position+4,SLIDER_BASE+3),
2073ee96407SJérôme Duval 		black);
2083ee96407SJérôme Duval 	AddLine(BPoint(position+4,SLIDER_BASE+3), BPoint(position,SLIDER_BASE+7),
2093ee96407SJérôme Duval 		black);
21042f70a5dSJérôme Duval 
21142f70a5dSJérôme Duval 
2123ee96407SJérôme Duval 	AddLine(BPoint(position-3,SLIDER_BASE+2), BPoint(position+3,SLIDER_BASE+2),
2133ee96407SJérôme Duval 		rose);
2143ee96407SJérôme Duval 	AddLine(BPoint(position-3,SLIDER_BASE+3), BPoint(position-1,SLIDER_BASE+5),
2153ee96407SJérôme Duval 		rose);
21642f70a5dSJérôme Duval 
2173ee96407SJérôme Duval 	AddLine(BPoint(position-2,SLIDER_BASE+3), BPoint(position+2,SLIDER_BASE+3),
2183ee96407SJérôme Duval 		red);
2193ee96407SJérôme Duval 	AddLine(BPoint(position-1,SLIDER_BASE+4), BPoint(position+1,SLIDER_BASE+4),
2203ee96407SJérôme Duval 		red);
2213ee96407SJérôme Duval 	AddLine(BPoint(position,SLIDER_BASE+5), BPoint(position,SLIDER_BASE+5),
2223ee96407SJérôme Duval 		red);
22342f70a5dSJérôme Duval 
2243ee96407SJérôme Duval 	AddLine(BPoint(position,SLIDER_BASE+6), BPoint(position+3,SLIDER_BASE+3),
2253ee96407SJérôme Duval 		bordeau);
22642f70a5dSJérôme Duval 
2273ee96407SJérôme Duval 	AddLine(BPoint(position,SLIDER_BASE+12), BPoint(position-4,SLIDER_BASE+16),
2283ee96407SJérôme Duval 		black);
2293ee96407SJérôme Duval 	AddLine(BPoint(position-4,SLIDER_BASE+16), BPoint(position-4,
2303ee96407SJérôme Duval 		SLIDER_BASE+17), black);
2313ee96407SJérôme Duval 	AddLine(BPoint(position-4,SLIDER_BASE+17), BPoint(position+4,
2323ee96407SJérôme Duval 		SLIDER_BASE+17), black);
2333ee96407SJérôme Duval 	AddLine(BPoint(position+4,SLIDER_BASE+17), BPoint(position+4,
2343ee96407SJérôme Duval 		SLIDER_BASE+16), black);
2353ee96407SJérôme Duval 	AddLine(BPoint(position+4,SLIDER_BASE+16), BPoint(position,SLIDER_BASE+12),
2363ee96407SJérôme Duval 		black);
2373ee96407SJérôme Duval 	AddLine(BPoint(position-4,SLIDER_BASE+18), BPoint(position+4,
2383ee96407SJérôme Duval 		SLIDER_BASE+18), white);
23942f70a5dSJérôme Duval 
2403ee96407SJérôme Duval 	AddLine(BPoint(position-3,SLIDER_BASE+16), BPoint(position,SLIDER_BASE+13),
2413ee96407SJérôme Duval 		rose);
24242f70a5dSJérôme Duval 
2433ee96407SJérôme Duval 	AddLine(BPoint(position-2,SLIDER_BASE+16), BPoint(position+2,
2443ee96407SJérôme Duval 		SLIDER_BASE+16), red);
2453ee96407SJérôme Duval 	AddLine(BPoint(position-1,SLIDER_BASE+15), BPoint(position+1,
2463ee96407SJérôme Duval 		SLIDER_BASE+15), red);
2473ee96407SJérôme Duval 	AddLine(BPoint(position,SLIDER_BASE+14), BPoint(position,
2483ee96407SJérôme Duval 		SLIDER_BASE+14), red);
24942f70a5dSJérôme Duval 
2503ee96407SJérôme Duval 	AddLine(BPoint(position+1,SLIDER_BASE+14), BPoint(position+3,
2513ee96407SJérôme Duval 		SLIDER_BASE+16), bordeau);
25242f70a5dSJérôme Duval 
25342f70a5dSJérôme Duval 	EndLineArray();
25442f70a5dSJérôme Duval }
25542f70a5dSJérôme Duval 
25642f70a5dSJérôme Duval 
25742f70a5dSJérôme Duval void
MouseMoved(BPoint point,uint32 transit,const BMessage * message)25842f70a5dSJérôme Duval TrackSlider::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
25942f70a5dSJérôme Duval {
26042f70a5dSJérôme Duval 	if (!IsTracking())
26142f70a5dSJérôme Duval 		return;
26242f70a5dSJérôme Duval 
26342f70a5dSJérôme Duval 	uint32 mouseButtons;
26442f70a5dSJérôme Duval 	BPoint where;
26542f70a5dSJérôme Duval 	GetMouse(&where, &mouseButtons, true);
26642f70a5dSJérôme Duval 
26742f70a5dSJérôme Duval 	// button not pressed, exit
26842f70a5dSJérôme Duval 	if (! (mouseButtons & B_PRIMARY_MOUSE_BUTTON)) {
26942f70a5dSJérôme Duval 		Invoke();
27042f70a5dSJérôme Duval 		SetTracking(false);
27142f70a5dSJérôme Duval 	}
27242f70a5dSJérôme Duval 
273ad0c65eaSJérôme Duval 	_UpdatePosition(point);
27442f70a5dSJérôme Duval }
27542f70a5dSJérôme Duval 
27642f70a5dSJérôme Duval 
27742f70a5dSJérôme Duval void
MouseDown(BPoint point)27842f70a5dSJérôme Duval TrackSlider::MouseDown(BPoint point)
27942f70a5dSJérôme Duval {
28042f70a5dSJérôme Duval 	if (!Bounds().InsetBySelf(2,2).Contains(point))
28142f70a5dSJérôme Duval 		return;
28242f70a5dSJérôme Duval 
283ad0c65eaSJérôme Duval 	_UpdatePosition(point);
28442f70a5dSJérôme Duval 	SetTracking(true);
2853ee96407SJérôme Duval 	SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY
2863ee96407SJérôme Duval 		| B_LOCK_WINDOW_FOCUS);
28742f70a5dSJérôme Duval }
28842f70a5dSJérôme Duval 
28942f70a5dSJérôme Duval 
29042f70a5dSJérôme Duval void
MouseUp(BPoint point)29142f70a5dSJérôme Duval TrackSlider::MouseUp(BPoint point)
29242f70a5dSJérôme Duval {
29342f70a5dSJérôme Duval 	if (!IsTracking())
29442f70a5dSJérôme Duval 		return;
29542f70a5dSJérôme Duval 	if (Bounds().InsetBySelf(2,2).Contains(point)) {
296ad0c65eaSJérôme Duval 		_UpdatePosition(point);
29742f70a5dSJérôme Duval 	}
29842f70a5dSJérôme Duval 
29942f70a5dSJérôme Duval 	fLeftTracking = fRightTracking = fMainTracking = false;
30042f70a5dSJérôme Duval 
30142f70a5dSJérôme Duval 	Invoke();
30242f70a5dSJérôme Duval 	SetTracking(false);
30342f70a5dSJérôme Duval 	Draw(Bounds());
30442f70a5dSJérôme Duval 	Flush();
30542f70a5dSJérôme Duval }
30642f70a5dSJérôme Duval 
30742f70a5dSJérôme Duval 
30842f70a5dSJérôme Duval void
_UpdatePosition(BPoint point)309ad0c65eaSJérôme Duval TrackSlider::_UpdatePosition(BPoint point)
31042f70a5dSJérôme Duval {
3113ee96407SJérôme Duval 	BRect leftRect(fBitmapView->fLeftX-9, SLIDER_BASE+3, fBitmapView->fLeftX,
3123ee96407SJérôme Duval 		SLIDER_BASE+16);
3133ee96407SJérôme Duval 	BRect rightRect(fBitmapView->fRightX, SLIDER_BASE+3,
3143ee96407SJérôme Duval 		fBitmapView->fRightX+9, SLIDER_BASE+16);
31542f70a5dSJérôme Duval 
3163ee96407SJérôme Duval 	if (!(fRightTracking || fMainTracking) && (fLeftTracking
3173ee96407SJérôme Duval 		|| ((point.x < fBitmapView->fPositionX-4) && leftRect.Contains(point)))) {
31842f70a5dSJérôme Duval 		if (!IsTracking())
31942f70a5dSJérôme Duval 			fBitmapView->fLastX = point.x - fBitmapView->fLeftX;
3203ee96407SJérôme Duval 		fBitmapView->fLeftX = MIN(MAX(point.x - fBitmapView->fLastX, 15),
3213ee96407SJérôme Duval 			fBitmapView->fRight);
3223ee96407SJérôme Duval 		fLeftTime = (bigtime_t)(MAX(MIN((fBitmapView->fLeftX - 15)
3233ee96407SJérôme Duval 			/ (fBitmapView->fRight - 14),1), 0) * fTotalTime);
32442f70a5dSJérôme Duval 		fLeftTracking = true;
32542f70a5dSJérôme Duval 
32642f70a5dSJérôme Duval 		BMessage msg = *Message();
32742f70a5dSJérôme Duval 		msg.AddInt64("left", fLeftTime);
32842f70a5dSJérôme Duval 
32942f70a5dSJérôme Duval 		if (fBitmapView->fPositionX < fBitmapView->fLeftX) {
33042f70a5dSJérôme Duval 			fBitmapView->fPositionX = fBitmapView->fLeftX + 1;
33142f70a5dSJérôme Duval 			fMainTime = fLeftTime;
33242f70a5dSJérôme Duval 			msg.AddInt64("main", fMainTime);
33342f70a5dSJérôme Duval 			if (fBitmapView->fRightX < fBitmapView->fPositionX) {
33442f70a5dSJérôme Duval 				fBitmapView->fRightX = fBitmapView->fPositionX;
33542f70a5dSJérôme Duval 				fRightTime = fMainTime;
33642f70a5dSJérôme Duval 				msg.AddInt64("right", fRightTime);
33742f70a5dSJérôme Duval 			}
33842f70a5dSJérôme Duval 		}
33942f70a5dSJérôme Duval 
34042f70a5dSJérôme Duval 		Invoke(&msg);
341ad0c65eaSJérôme Duval 		_RenderBitmap();
34242f70a5dSJérôme Duval 
343*425ac1b6SAlexander von Gluck IV 		//printf("fLeftPos : %lld\n", fLeftTime);
3443ee96407SJérôme Duval 	} else if (!fMainTracking && (fRightTracking
3453ee96407SJérôme Duval 		|| ((point.x > fBitmapView->fPositionX+4)
3463ee96407SJérôme Duval 		&& rightRect.Contains(point)))) {
34742f70a5dSJérôme Duval 		if (!IsTracking())
34842f70a5dSJérôme Duval 			fBitmapView->fLastX = point.x - fBitmapView->fRightX;
3493ee96407SJérôme Duval 		fBitmapView->fRightX = MIN(MAX(point.x - fBitmapView->fLastX, 15),
3503ee96407SJérôme Duval 			fBitmapView->fRight);
3513ee96407SJérôme Duval 		fRightTime = (bigtime_t)(MAX(MIN((fBitmapView->fRightX - 15)
3523ee96407SJérôme Duval 			/ (fBitmapView->fRight - 14),1), 0) * fTotalTime);
35342f70a5dSJérôme Duval 		fRightTracking = true;
35442f70a5dSJérôme Duval 
35542f70a5dSJérôme Duval 		BMessage msg = *Message();
35642f70a5dSJérôme Duval 		msg.AddInt64("right", fRightTime);
35742f70a5dSJérôme Duval 
35842f70a5dSJérôme Duval 		if (fBitmapView->fPositionX > fBitmapView->fRightX) {
35942f70a5dSJérôme Duval 			fBitmapView->fPositionX = fBitmapView->fRightX;
36042f70a5dSJérôme Duval 			fMainTime = fRightTime;
36142f70a5dSJérôme Duval 			msg.AddInt64("main", fMainTime);
36242f70a5dSJérôme Duval 			if (fBitmapView->fLeftX > fBitmapView->fPositionX) {
36342f70a5dSJérôme Duval 				fBitmapView->fLeftX = fBitmapView->fPositionX - 1;
36442f70a5dSJérôme Duval 				fLeftTime = fMainTime;
36542f70a5dSJérôme Duval 				msg.AddInt64("left", fLeftTime);
36642f70a5dSJérôme Duval 			}
36742f70a5dSJérôme Duval 		}
36842f70a5dSJérôme Duval 
36942f70a5dSJérôme Duval 		Invoke(&msg);
370ad0c65eaSJérôme Duval 		_RenderBitmap();
37142f70a5dSJérôme Duval 
372*425ac1b6SAlexander von Gluck IV 		//printf("fRightPos : %lld\n", fRightTime);
37342f70a5dSJérôme Duval 	} else {
37442f70a5dSJérôme Duval 		fBitmapView->fPositionX = MIN(MAX(point.x, 15), fBitmapView->fRight);
3753ee96407SJérôme Duval 		fMainTime = (bigtime_t)(MAX(MIN((fBitmapView->fPositionX - 15)
3763ee96407SJérôme Duval 			/ (fBitmapView->fRight - 14),1), 0) * fTotalTime);
37742f70a5dSJérôme Duval 		fMainTracking = true;
37842f70a5dSJérôme Duval 
37942f70a5dSJérôme Duval 		BMessage msg = *Message();
38042f70a5dSJérôme Duval 		msg.AddInt64("main", fMainTime);
38142f70a5dSJérôme Duval 
38242f70a5dSJérôme Duval 		if (fBitmapView->fRightX < fBitmapView->fPositionX) {
38342f70a5dSJérôme Duval 			fBitmapView->fRightX = fBitmapView->fPositionX;
38442f70a5dSJérôme Duval 			fRightTime = fMainTime;
38542f70a5dSJérôme Duval 			msg.AddInt64("right", fRightTime);
386ad0c65eaSJérôme Duval 			_RenderBitmap();
38742f70a5dSJérôme Duval 		} else if (fBitmapView->fLeftX > fBitmapView->fPositionX) {
38842f70a5dSJérôme Duval 			fBitmapView->fLeftX = fBitmapView->fPositionX - 1;
38942f70a5dSJérôme Duval 			fLeftTime = fMainTime;
39042f70a5dSJérôme Duval 			msg.AddInt64("left", fLeftTime);
391ad0c65eaSJérôme Duval 			_RenderBitmap();
39242f70a5dSJérôme Duval 		}
39342f70a5dSJérôme Duval 
39442f70a5dSJérôme Duval 		Invoke(&msg);
395*425ac1b6SAlexander von Gluck IV 		//printf("fPosition : %lld\n", fMainTime);
39642f70a5dSJérôme Duval 	}
39742f70a5dSJérôme Duval 	Draw(Bounds());
39842f70a5dSJérôme Duval 	Flush();
39942f70a5dSJérôme Duval }
40042f70a5dSJérôme Duval 
40142f70a5dSJérôme Duval 
40242f70a5dSJérôme Duval void
_TimeToString(bigtime_t timestamp,char * string)403ad0c65eaSJérôme Duval TrackSlider::_TimeToString(bigtime_t timestamp, char *string)
40442f70a5dSJérôme Duval {
40542f70a5dSJérôme Duval 	uint32 hours = timestamp / 3600000000LL;
40642f70a5dSJérôme Duval 	timestamp -= hours * 3600000000LL;
40742f70a5dSJérôme Duval 	uint32 minutes = timestamp / 60000000LL;
40842f70a5dSJérôme Duval 	timestamp -= minutes * 60000000LL;
40942f70a5dSJérôme Duval 	uint32 seconds = timestamp / 1000000LL;
41042f70a5dSJérôme Duval 	timestamp -= seconds * 1000000LL;
41142f70a5dSJérôme Duval 	uint32 centiseconds = timestamp / 10000LL;
4127f4d1af4SSergei Reznikov 	sprintf(string, "%02" B_PRId32 ":%02" B_PRId32 ":%02" B_PRId32 ":%02"
4137f4d1af4SSergei Reznikov 		B_PRId32, hours, minutes, seconds, centiseconds);
41442f70a5dSJérôme Duval }
41542f70a5dSJérôme Duval 
41642f70a5dSJérôme Duval 
41742f70a5dSJérôme Duval void
SetMainTime(bigtime_t timestamp,bool reset)41842f70a5dSJérôme Duval TrackSlider::SetMainTime(bigtime_t timestamp, bool reset)
41942f70a5dSJérôme Duval {
42042f70a5dSJérôme Duval 	fMainTime = timestamp;
4213ee96407SJérôme Duval 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14)
4223ee96407SJérôme Duval 		* ((double)fMainTime / fTotalTime);
42342f70a5dSJérôme Duval 	if (reset) {
42442f70a5dSJérôme Duval 		fRightTime = fTotalTime;
42542f70a5dSJérôme Duval 		fLeftTime = 0;
4263ee96407SJérôme Duval 		fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15)
4273ee96407SJérôme Duval 			* ((double)fLeftTime / fTotalTime);
4283ee96407SJérôme Duval 		fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16)
4293ee96407SJérôme Duval 			* ((double)fRightTime / fTotalTime);
430ad0c65eaSJérôme Duval 		_RenderBitmap();
43142f70a5dSJérôme Duval 	}
43242f70a5dSJérôme Duval 	Invalidate();
43342f70a5dSJérôme Duval }
43442f70a5dSJérôme Duval 
43542f70a5dSJérôme Duval void
SetTotalTime(bigtime_t timestamp,bool reset)43642f70a5dSJérôme Duval TrackSlider::SetTotalTime(bigtime_t timestamp, bool reset)
43742f70a5dSJérôme Duval {
43842f70a5dSJérôme Duval 	fTotalTime = timestamp;
43942f70a5dSJérôme Duval 	if (reset) {
44042f70a5dSJérôme Duval 		fMainTime = 0;
44142f70a5dSJérôme Duval 		fRightTime = fTotalTime;
44242f70a5dSJérôme Duval 		fLeftTime = 0;
44342f70a5dSJérôme Duval 	}
4443ee96407SJérôme Duval 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14)
4453ee96407SJérôme Duval 		* ((double)fMainTime / fTotalTime);
4463ee96407SJérôme Duval 	fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15)
4473ee96407SJérôme Duval 		* ((double)fLeftTime / fTotalTime);
4483ee96407SJérôme Duval 	fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16)
4493ee96407SJérôme Duval 		* ((double)fRightTime / fTotalTime);
450ad0c65eaSJérôme Duval 	_RenderBitmap();
45142f70a5dSJérôme Duval 	Invalidate();
45242f70a5dSJérôme Duval }
45342f70a5dSJérôme Duval 
45442f70a5dSJérôme Duval 
45542f70a5dSJérôme Duval void
ResetMainTime()45642f70a5dSJérôme Duval TrackSlider::ResetMainTime()
45742f70a5dSJérôme Duval {
45842f70a5dSJérôme Duval 	fMainTime = fLeftTime;
4593ee96407SJérôme Duval 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14)
4603ee96407SJérôme Duval 		* ((double)fMainTime / fTotalTime);
46142f70a5dSJérôme Duval 	Invalidate();
46242f70a5dSJérôme Duval }
46342f70a5dSJérôme Duval 
46442f70a5dSJérôme Duval 
46542f70a5dSJérôme Duval void
FrameResized(float width,float height)46642f70a5dSJérôme Duval TrackSlider::FrameResized(float width, float height)
46742f70a5dSJérôme Duval {
46842f70a5dSJérôme Duval 	fBitmapView->fRight = Bounds().right - kLeftRightTrackSliderWidth;
4693ee96407SJérôme Duval 	fBitmapView->fPositionX = 15 + (fBitmapView->fRight - 14)
4703ee96407SJérôme Duval 		* ((double)fMainTime / fTotalTime);
471ad0c65eaSJérôme Duval 	_InitBitmap();
4723ee96407SJérôme Duval 	fBitmapView->fLeftX = 14 + (fBitmapView->fRight - 15)
4733ee96407SJérôme Duval 		* ((double)fLeftTime / fTotalTime);
4743ee96407SJérôme Duval 	fBitmapView->fRightX = 15 + (fBitmapView->fRight - 16)
4753ee96407SJérôme Duval 		* ((double)fRightTime / fTotalTime);
476ad0c65eaSJérôme Duval 	_RenderBitmap();
47742f70a5dSJérôme Duval 	Invalidate();
47842f70a5dSJérôme Duval }
47942f70a5dSJérôme Duval 
48042f70a5dSJérôme Duval 
SliderOffscreenView(BRect frame,const char * name)4814c9da6dcSStephan Aßmus SliderOffscreenView::SliderOffscreenView(BRect frame, const char *name)
48242f70a5dSJérôme Duval 	: BView(frame, name, B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW),
48342f70a5dSJérôme Duval 	leftBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8),
48442f70a5dSJérôme Duval 	rightBitmap(BRect(BPoint(0,0), kLeftRightTrackSliderSize), B_CMAP8),
4853ee96407SJérôme Duval 	leftThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1,
4863ee96407SJérôme Duval 		kLeftRightThumbHeight - 1), B_CMAP8),
4873ee96407SJérôme Duval 	rightThumbBitmap(BRect(0, 0, kLeftRightThumbWidth - 1,
4883ee96407SJérôme Duval 		kLeftRightThumbHeight - 1), B_CMAP8)
48942f70a5dSJérôme Duval {
4903ee96407SJérôme Duval 	leftBitmap.SetBits(kLeftTrackSliderBits,
4913ee96407SJérôme Duval 		kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8);
4923ee96407SJérôme Duval 	rightBitmap.SetBits(kRightTrackSliderBits,
4933ee96407SJérôme Duval 		kLeftRightTrackSliderWidth * kLeftRightTrackSliderHeight, 0, B_CMAP8);
4943ee96407SJérôme Duval 	leftThumbBitmap.SetBits(kLeftThumbBits,
4953ee96407SJérôme Duval 		kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8);
4963ee96407SJérôme Duval 	rightThumbBitmap.SetBits(kRightThumbBits,
4973ee96407SJérôme Duval 		kLeftRightThumbWidth * kLeftRightThumbHeight, 0, B_CMAP8);
49842f70a5dSJérôme Duval }
49942f70a5dSJérôme Duval 
50042f70a5dSJérôme Duval 
~SliderOffscreenView()50142f70a5dSJérôme Duval SliderOffscreenView::~SliderOffscreenView()
50242f70a5dSJérôme Duval {
50342f70a5dSJérôme Duval 
50442f70a5dSJérôme Duval }
50542f70a5dSJérôme Duval 
50642f70a5dSJérôme Duval 
50742f70a5dSJérôme Duval void
DrawX()50842f70a5dSJérôme Duval SliderOffscreenView::DrawX()
50942f70a5dSJérôme Duval {
5105fa040e3SStephan Aßmus 	SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
51142f70a5dSJérôme Duval 	FillRect(Bounds());
51242f70a5dSJérôme Duval 
51357e2f323SJérôme Duval 	SetHighColor(189, 186, 189);
51457e2f323SJérôme Duval 	StrokeLine(BPoint(11, SLIDER_BASE + 1), BPoint(fRight, SLIDER_BASE + 1));
51557e2f323SJérôme Duval 	SetHighColor(0, 0, 0);
51657e2f323SJérôme Duval 	StrokeLine(BPoint(11, SLIDER_BASE + 2), BPoint(fRight, SLIDER_BASE + 2));
51757e2f323SJérôme Duval 	SetHighColor(255, 255, 255);
51857e2f323SJérôme Duval 	StrokeLine(BPoint(11, SLIDER_BASE + 17), BPoint(fRight, SLIDER_BASE + 17));
51957e2f323SJérôme Duval 	SetHighColor(231, 227, 231);
52057e2f323SJérôme Duval 	StrokeLine(BPoint(11, SLIDER_BASE + 18), BPoint(fRight, SLIDER_BASE + 18));
52157e2f323SJérôme Duval 
52257e2f323SJérôme Duval 	SetDrawingMode(B_OP_OVER);
52357e2f323SJérôme Duval 	SetLowColor(HighColor());
52457e2f323SJérôme Duval 
52557e2f323SJérôme Duval 	BPoint leftPoint(5, SLIDER_BASE + 1);
5263ee96407SJérôme Duval 	DrawBitmapAsync(&leftBitmap, BRect(BPoint(0, 0),
5273ee96407SJérôme Duval 		kLeftRightTrackSliderSize - BPoint(5, 0)),
52857e2f323SJérôme Duval 		BRect(leftPoint, leftPoint + kLeftRightTrackSliderSize - BPoint(5, 0)));
52957e2f323SJérôme Duval 	BPoint rightPoint(fRight + 1, SLIDER_BASE + 1);
53057e2f323SJérôme Duval 	DrawBitmapAsync(&rightBitmap, BRect(BPoint(5, 0), kLeftRightTrackSliderSize),
53157e2f323SJérôme Duval 		BRect(rightPoint, rightPoint + kLeftRightTrackSliderSize-BPoint(5, 0)));
53257e2f323SJérôme Duval 
53357e2f323SJérôme Duval 	SetHighColor(153, 153, 153);
53457e2f323SJérôme Duval 	FillRect(BRect(11, SLIDER_BASE + 3, fLeftX - 9, SLIDER_BASE + 16));
53557e2f323SJérôme Duval 	FillRect(BRect(fRightX + 9, SLIDER_BASE + 3, fRight, SLIDER_BASE + 16));
53657e2f323SJérôme Duval 	if (fLeftX > 19) {
5373ee96407SJérôme Duval 		StrokeLine(BPoint(fLeftX - 9, SLIDER_BASE + 3), BPoint(fLeftX - 6,
5383ee96407SJérôme Duval 			SLIDER_BASE + 3));
5393ee96407SJérôme Duval 		StrokeLine(BPoint(fLeftX - 9, SLIDER_BASE + 4), BPoint(fLeftX - 7,
5403ee96407SJérôme Duval 			SLIDER_BASE + 4));
5413ee96407SJérôme Duval 		StrokeLine(BPoint(fLeftX - 9, SLIDER_BASE + 5), BPoint(fLeftX - 8,
5423ee96407SJérôme Duval 			SLIDER_BASE + 5));
5433ee96407SJérôme Duval 		StrokeLine(BPoint(fLeftX - 9, SLIDER_BASE + 16), BPoint(fLeftX - 6,
5443ee96407SJérôme Duval 			SLIDER_BASE + 16));
5453ee96407SJérôme Duval 		StrokeLine(BPoint(fLeftX - 9, SLIDER_BASE + 15), BPoint(fLeftX - 7,
5463ee96407SJérôme Duval 			SLIDER_BASE + 15));
5473ee96407SJérôme Duval 		StrokeLine(BPoint(fLeftX - 9, SLIDER_BASE + 14), BPoint(fLeftX - 8,
5483ee96407SJérôme Duval 			SLIDER_BASE + 14));
54957e2f323SJérôme Duval 	}
55057e2f323SJérôme Duval 	if (fRightX < fRight - 5) {
5513ee96407SJérôme Duval 		StrokeLine(BPoint(fRightX + 5, SLIDER_BASE + 3), BPoint(fRightX + 8,
5523ee96407SJérôme Duval 			SLIDER_BASE + 3));
5533ee96407SJérôme Duval 		StrokeLine(BPoint(fRightX + 7, SLIDER_BASE + 4), BPoint(fRightX + 8,
5543ee96407SJérôme Duval 			SLIDER_BASE + 4));
5553ee96407SJérôme Duval 		StrokeLine(BPoint(fRightX + 8, SLIDER_BASE + 5), BPoint(fRightX + 8,
5563ee96407SJérôme Duval 			SLIDER_BASE + 6));
5573ee96407SJérôme Duval 		StrokeLine(BPoint(fRightX + 8, SLIDER_BASE + 13), BPoint(fRightX + 8,
5583ee96407SJérôme Duval 			SLIDER_BASE + 14));
5593ee96407SJérôme Duval 		StrokeLine(BPoint(fRightX + 5, SLIDER_BASE + 16), BPoint(fRightX + 8,
5603ee96407SJérôme Duval 			SLIDER_BASE + 16));
5613ee96407SJérôme Duval 		StrokeLine(BPoint(fRightX + 7, SLIDER_BASE + 15), BPoint(fRightX + 8,
5623ee96407SJérôme Duval 			SLIDER_BASE + 15));
56357e2f323SJérôme Duval 	}
56457e2f323SJérôme Duval 	SetHighColor(144, 186, 136);
56557e2f323SJérôme Duval 	FillRect(BRect(fLeftX + 1, SLIDER_BASE + 3, fRightX, SLIDER_BASE + 4));
56657e2f323SJérôme Duval 	FillRect(BRect(fLeftX + 1, SLIDER_BASE + 5, fLeftX + 2, SLIDER_BASE + 16));
56757e2f323SJérôme Duval 	SetHighColor(171, 221, 161);
56857e2f323SJérôme Duval 	FillRect(BRect(fLeftX + 3, SLIDER_BASE + 5, fRightX, SLIDER_BASE + 16));
56957e2f323SJérôme Duval 
57057e2f323SJérôme Duval 	int i = 17;
57157e2f323SJérôme Duval 	int j = 18;
57257e2f323SJérôme Duval 	SetHighColor(128, 128, 128);
57357e2f323SJérôme Duval 	for (; i < fLeftX - 9; i += 6) {
57457e2f323SJérôme Duval 		StrokeLine(BPoint(i, SLIDER_BASE + 7), BPoint(i, SLIDER_BASE + 13));
57557e2f323SJérôme Duval 	}
57657e2f323SJérôme Duval 	SetHighColor(179, 179, 179);
57757e2f323SJérôme Duval 	for (; j < fLeftX - 9; j += 6) {
57857e2f323SJérôme Duval 		StrokeLine(BPoint(j, SLIDER_BASE + 7), BPoint(j, SLIDER_BASE + 13));
57957e2f323SJérôme Duval 	}
58057e2f323SJérôme Duval 
58157e2f323SJérôme Duval 	while (i <= fLeftX)
58257e2f323SJérôme Duval 		i += 6;
58357e2f323SJérôme Duval 	while (j <= fLeftX)
58457e2f323SJérôme Duval 		j += 6;
58557e2f323SJérôme Duval 
58657e2f323SJérôme Duval 	SetHighColor(144, 186, 136);
58757e2f323SJérôme Duval 	for (; i <= fRightX; i += 6) {
58857e2f323SJérôme Duval 		StrokeLine(BPoint(i, SLIDER_BASE + 7), BPoint(i, SLIDER_BASE + 13));
58957e2f323SJérôme Duval 	}
59057e2f323SJérôme Duval 	SetHighColor(189, 244, 178);
59157e2f323SJérôme Duval 	for (; j <= fRightX; j += 6) {
59257e2f323SJérôme Duval 		StrokeLine(BPoint(j, SLIDER_BASE + 7), BPoint(j, SLIDER_BASE + 13));
59357e2f323SJérôme Duval 	}
59457e2f323SJérôme Duval 
59557e2f323SJérôme Duval 	while (i <= fRightX + 9)
59657e2f323SJérôme Duval 		i += 6;
59757e2f323SJérôme Duval 	while (j <= fRightX + 9)
59857e2f323SJérôme Duval 		j += 6;
59957e2f323SJérôme Duval 
60057e2f323SJérôme Duval 	SetHighColor(128, 128, 128);
60157e2f323SJérôme Duval 	for (; i <= fRight + 1; i += 6) {
60257e2f323SJérôme Duval 		StrokeLine(BPoint(i, SLIDER_BASE + 7), BPoint(i, SLIDER_BASE + 13));
60357e2f323SJérôme Duval 	}
60457e2f323SJérôme Duval 	SetHighColor(179, 179, 179);
60557e2f323SJérôme Duval 	for (; j <= fRight + 1; j += 6) {
60657e2f323SJérôme Duval 		StrokeLine(BPoint(j, SLIDER_BASE + 7), BPoint(j, SLIDER_BASE + 13));
60757e2f323SJérôme Duval 	}
60857e2f323SJérôme Duval 
60957e2f323SJérôme Duval 	SetLowColor(HighColor());
61057e2f323SJérôme Duval 
61157e2f323SJérôme Duval 	BPoint leftThumbPoint(fLeftX - 8, SLIDER_BASE + 3);
6123ee96407SJérôme Duval 	DrawBitmapAsync(&leftThumbBitmap, BRect(BPoint(0, 0),
6133ee96407SJérôme Duval 		kLeftRightThumbSize - BPoint(7, 0)),
6143ee96407SJérôme Duval 		BRect(leftThumbPoint, leftThumbPoint
6153ee96407SJérôme Duval 			+ kLeftRightThumbSize - BPoint(7, 0)));
61657e2f323SJérôme Duval 
61757e2f323SJérôme Duval 	BPoint rightThumbPoint(fRightX, SLIDER_BASE + 3);
6183ee96407SJérôme Duval 	DrawBitmapAsync(&rightThumbBitmap, BRect(BPoint(6, 0),
6193ee96407SJérôme Duval 		kLeftRightThumbSize),
6203ee96407SJérôme Duval 		BRect(rightThumbPoint, rightThumbPoint
6213ee96407SJérôme Duval 			+ kLeftRightThumbSize-BPoint(6, 0)));
62257e2f323SJérôme Duval 
62342f70a5dSJérôme Duval 	Sync();
62457e2f323SJérôme Duval }
625