unit glJuke; interface uses glUtils,glUi,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls,math,jpeg,main,global; const ROTATION_TIMER_INTERVAL = 30; BORDER_TOPHEIGHT=17; BORDER_BOTTOMHEIGHT=10; type TGLPanel = class(TCustomControl) GLTimer: TTimer; procedure GLTimerTimer(Sender: TObject); procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);override; procedure MouseMove( Shift: TShiftState; X, Y: Integer);override; procedure Draw; Procedure MoveLeft; Procedure MoveRight; procedure Resize;override; procedure SetLbEnabled(var l : tglListbox); procedure Paint;override; //procedure FormClose(Sender: TObject; var Action: TCloseAction); constructor Create(AOwner: TComponent);override; procedure init(); procedure NoAlbums; private { Private declarations } ControlSet : TglControlSet; Background: array [0..0] of TglBitmap; moveinprogress : boolean; flastrotation : integer; bnd : integer; prev_dir : integer; procedure createControls; procedure doautorotation(stop : integer;rot : integer;enable : TGLListbox); public { Public declarations } Artwork : array[0..3] of TglBitmap; Titles : array[0..3] of TglListbox; AddAll : array[0..3] of TglLabel; //Arrows : array[0..1] of TglColourQuad; property lastrotation : integer read flastrotation write flastrotation; end; type TColorRec = packed record b,g,r,a: Byte; end; var angle : single; DC:HDC; RC:HGLRC; rotation : integer = 0; //lastrotation : integer =0; velocity : integer; starttime : dword =0; endtime : dword =0; startpoint : integer; endpoint : integer; implementation uses jukeboxform; procedure TGLPanel.MoveLeft; begin if moveinprogress=true then exit; MouseDown(mbLeft,[],width div 2,300); application.processmessages; MouseMove([],0,300); application.processmessages; MouseUp(mbLeft,[],0,300); moveinprogress:=false; end; procedure TGLPanel.MoveRight; begin if moveinprogress=true then exit; MouseDown(mbLeft,[],width div 2,300); application.processmessages; MouseMove([],width,300); application.processmessages; MouseUp(mbLeft,[],width,300); moveinprogress:=false; end; procedure TGLPanel.createControls; var n : integer; obmp : Tbitmap; tr : Trect; dr : Trect; a : tgl3DCoord; b : tgl3DCoord; const addallx1=1.3; addallx2=1.5; addally1=-0.75; addally2=-0.7; addallz=1.5001; begin bnd:=0; ControlSet:=TglControlSet.Create(self); ControlSet.RedrawProcedure:=draw; obmp:=tbitmap.create; tr.top:=1; tr.left:=0; tr.right:=jukebox.ThreeDPanel.width; tr.bottom:=jukebox.ThreeDPanel.height; dr.Left:=0; dr.Top:=0; dr.Right:=tr.Right; dr.Bottom:=tr.Bottom; obmp.width:=Width; obmp.height:=tr.Bottom; obmp.Canvas.CopyRect(dr,jukebox.midpanel.Canvas,tr); //obmp.SaveToFile('c:\temp.bmp'); Background[0]:=TglBitmap.Create(ControlSet); with Background[0] do begin name:='Background'; nodraw:=true; bitmap:=obmp; Normal:=gl3D(0,0,1); with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; a:=getGLPos(0,0); b:=getGLPos(width,height); with Vertices do begin v1:=gl3d(-2.1,-2.5,-5); v2:=gl3d(2.1,-2.5,-5); v3:=gl3d(2.1,0.5,-5); v4:=gl3d(-2.1,0.5,-5); end; end; obmp.Free; //Front Artwork[0]:=TglBitmap.Create(ControlSet); with ArtWork[0] do begin name:='Front Cover'; //filename:='\idc\mp3\Florence and the Machine__Lungs\title.jpg'; Normal:=gl3D(0,0,1); with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(-1.5, -0.75, 1.5); v2:=gl3d(0, -0.75, 1.5); v3:=gl3d(0, 0.75, 1.5); v4:=gl3d(-1.5, 0.75, 1.5); end; end; //Right Artwork[1]:=TglBitmap.Create(ControlSet); with ArtWork[1] do begin name:='Right Cover'; //filename:='\idc\mp3\Roxy Music__Avalon\title.jpg'; Normal:=gl3D(1,0,0); with Texture do begin v1:=gl2D(1,0); v2:=gl2d(1,1); v3:=gl2d(0,1); v4:=gl2d(0,0); end; with Vertices do begin v1:=gl3d(1.5, -0.75, 0); v2:=gl3d(1.5, 0.75, 0); v3:=gl3d(1.5, 0.75, 1.5); v4:=gl3d(1.5, -0.75, 1.5); end; end; //Back Artwork[2]:=TglBitmap.Create(ControlSet); with ArtWork[2] do begin name:='Back Cover'; //filename:='\idc\mp3\Elvis Presley__The collection vol 4\title.jpg'; Normal:=gl3D(0,0,-1); with Texture do begin v1:=gl2D(1,0); v2:=gl2d(1,1); v3:=gl2d(0,1); v4:=gl2d(0,0); end; with Vertices do begin v1:=gl3d(0, -0.75, -1.5); v2:=gl3d(0, 0.75, -1.5); v3:=gl3d(1.5, 0.75, -1.5); v4:=gl3d(1.5, -0.75, -1.5); end; end; //Left Artwork[3]:=TglBitmap.Create(ControlSet); with ArtWork[3] do begin name:='Left Cover'; //filename:='\idc\mp3\Beatles__Revolver\title.jpg'; Normal:=gl3D(-1,0,0); with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(-1.5, -0.75, -1.5); v2:=gl3d(-1.5, -0.75, 0); v3:=gl3d(-1.5, 0.75, 0); v4:=gl3d(-1.5, 0.75, -1.5); end; end; Titles[0]:=tglListbox.Create(ControlSet); with Titles[0] do begin onClick:=jukebox.lsbClick; name:='Front Listbox'; font.name:=jukebox.lsb1.font.name; font.size:=jukebox.lsb1.font.size; moretext:=jukebox.lsb1.moretext; linespacing:=jukebox.lsb1.linespacing; margin:=aspx(5); Normal:=gl3D(0,0,1); with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(0, -0.75, 1.5); v2:=gl3d(1.5, -0.75, 1.5); v3:=gl3d(1.5, 0.75, 1.5); v4:=gl3d(0, 0.75, 1.5); end; end; Titles[1]:=tglListbox.Create(ControlSet); with Titles[1] do begin onClick:=jukebox.lsbClick; name:='Right Listbox'; font.name:=Titles[0].font.name; font.size:=Titles[0].font.size; moretext:=Titles[0].moretext; linespacing:=Titles[0].linespacing; margin:=Titles[0].margin; Normal:=gl3D(1,0,0); with Texture do begin v1:=gl2D(1,0); v2:=gl2d(1,1); v3:=gl2d(0,1); v4:=gl2d(0,0); end; with Vertices do begin v1:=gl3d(1.5, -0.75, -1.5); v2:=gl3d(1.5, 0.75, -1.5); v3:=gl3d(1.5, 0.75, -0); v4:=gl3d(1.5, -0.75, -0); end; end; Titles[2]:=tglListBox.Create(ControlSet); with Titles[2] do begin onClick:=jukebox.lsbClick; name:='Back Listbox'; font.name:=Titles[0].font.name; font.size:=Titles[0].font.size; moretext:=Titles[0].moretext; linespacing:=Titles[0].linespacing; margin:=Titles[0].margin; Normal:=gl3D(0,0,-1); with Texture do begin v1:=gl2D(1,0); v2:=gl2d(1,1); v3:=gl2d(0,1); v4:=gl2d(0,0); end; with Vertices do begin v1:=gl3d(-1.5, -0.75, -1.5); v2:=gl3d(-1.5, 0.75, -1.5); v3:=gl3d(0, 0.75, -1.5); v4:=gl3d(0, -0.75, -1.5); end; end; Titles[3]:=tglListBox.Create(ControlSet); with Titles[3] do begin onClick:=jukebox.lsbClick; name:='Left Listbox'; font.name:=Titles[0].font.name; font.size:=Titles[0].font.size; moretext:=Titles[0].moretext; linespacing:=Titles[0].linespacing; margin:=Titles[0].margin; Normal:=gl3D(-1,0,0); with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(-1.5, -0.75, 0); v2:=gl3d(-1.5, -0.75, 1.5); v3:=gl3d(-1.5, 0.75, 1.5); v4:=gl3d(-1.5, 0.75, 0); end; end; AddAll[0]:=TglLabel.Create(ControlSet); with AddAll[0] do begin name:='AddAll_Front'; caption:='Add All'; font.name:=jukebox.lsb1.font.name; font.size:=jukebox.lsb1.font.size; onclick:=jukebox.playall3d; Normal:=gl3D(0,0,1); with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(addallx1, addally1, addallz); v2:=gl3d(addallx2, addally1, addallz); v3:=gl3d(addallx2, addally2, addallz); v4:=gl3d(addallx1, addally2, addallz); end; end; AddAll[1]:=TglLabel.Create(ControlSet); with AddAll[1] do begin name:='AddAll_Right'; caption:='Add All'; font.name:=jukebox.lsb1.font.name; font.size:=jukebox.lsb1.font.size; onclick:=jukebox.playall3d; Normal:=gl3D(1,0,0); with Texture do begin v1:=gl2D(1,0); v2:=gl2d(1,1); v3:=gl2d(0,1); v4:=gl2d(0,0); end; with Vertices do begin v1:=gl3d(addallz, addally1, 0-addallx2); v2:=gl3d(addallz, addally2, 0-addallx2); v3:=gl3d(addallz, addally2, 0-addallx1); v4:=gl3d(addallz, addally1, 0-addallx1); end; end; AddAll[2]:=TglLabel.Create(ControlSet); with AddAll[2] do begin name:='AddAll_Back'; caption:='Add All'; font.name:=jukebox.lsb1.font.name; font.size:=jukebox.lsb1.font.size; onclick:=jukebox.playall3d; Normal:=gl3D(0,0,-1); with Texture do begin v1:=gl2D(1,0); v2:=gl2d(1,1); v3:=gl2d(0,1); v4:=gl2d(0,0); end; with Vertices do begin v1:=gl3d(0-addallx2, addally1, 0-addallz); v2:=gl3d(0-addallx2, addally2, 0-addallz); v3:=gl3d(0-addallx1, addally2, 0-addallz); v4:=gl3d(0-addallx1, addally1, 0-addallz); end; end; AddAll[3]:=TglLabel.Create(ControlSet); with AddAll[3] do begin name:='AddAll_Left'; caption:='Add All'; font.name:=jukebox.lsb1.font.name; font.size:=jukebox.lsb1.font.size; onclick:=jukebox.playall3D; Normal:=gl3D(-1,0,0); with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(0-addallz, addally1, addallx1); v2:=gl3d(0-addallz, addally1, addallx2); v3:=gl3d(0-addallz, addally2, addallx2); v4:=gl3d(0-addallz, addally2, addallx1); end; end; { Arrows[0]:=TglColourQuad.Create(ControlSet); with Arrows[0] do begin name:='Left to Right arrow'; Normal:=gl3D(0,0,1); //nodraw:=true; with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(-2.3, -1.65, 0); v2:=gl3d(2.3, -1.72, 0); v3:=gl3d(2.3, -1.75, 0); v4:=gl3d(-2.3, -1.85, 0); end; end; Arrows[1]:=TglColourQuad.Create(ControlSet); with Arrows[1] do begin name:='Right to Left arrow'; Normal:=gl3D(1,0,0); //nodraw:=true; with Texture do begin v1:=gl2D(0,0); v2:=gl2d(1,0); v3:=gl2d(1,1); v4:=gl2d(0,1); end; with Vertices do begin v1:=gl3d(-2.3, -1.72+0.2, 0); v2:=gl3d(2.3, -1.65+0.2, 0); v3:=gl3d(2.3, -1.85+0.2, 0); v4:=gl3d(-2.3, -1.75+0.2, 0); end; end; } draw; titles[0].clear; titles[0].drawmode:=true; titles[0].realworldwidth:=round(getRealWorldPos(titles[0].Vertices.v3).x-getRealWorldPos(titles[0].Vertices.v1).x); titles[0].realworldheight:=round(getRealWorldPos(titles[0].Vertices.v1).y-getRealWorldPos(titles[0].Vertices.v3).y); titles[0].Resize; titles[1].clear; titles[1].drawmode:=true; titles[1].realworldwidth:=titles[0].realworldwidth; titles[1].realworldheight:=titles[0].realworldheight; titles[1].Resize; titles[2].clear; titles[2].drawmode:=true; titles[2].realworldwidth:=titles[0].realworldwidth; titles[2].realworldheight:=titles[0].realworldheight; titles[2].Resize; titles[3].clear; titles[3].drawmode:=true; titles[3].realworldwidth:=titles[0].realworldwidth; titles[3].realworldheight:=titles[0].realworldheight; titles[3].Resize; draw; setlbenabled(titles[0]); randomize; end; procedure setupPixelFormat(DC:HDC); const pfd:TPIXELFORMATDESCRIPTOR = ( nSize:sizeof(TPIXELFORMATDESCRIPTOR); // size nVersion:1; // version dwFlags:PFD_SUPPORT_OPENGL or PFD_DRAW_TO_WINDOW or PFD_DOUBLEBUFFER; // support double-buffering iPixelType:PFD_TYPE_RGBA; // color type cColorBits:24; // prefered color depth cRedBits:0; cRedShift:0; // color bits (ignored) cGreenBits:0; cGreenShift:0; cBlueBits:0; cBlueShift:0; cAlphaBits:0; cAlphaShift:0; // no alpha buffer cAccumBits: 0; cAccumRedBits: 0; // no accumulation buffer, cAccumGreenBits: 0; // accum bits (ignored) cAccumBlueBits: 0; cAccumAlphaBits: 0; cDepthBits:16; // depth buffer cStencilBits:0; // no stencil buffer cAuxBuffers:0; // no auxiliary buffers iLayerType:PFD_MAIN_PLANE; // main layer bReserved: 0; dwLayerMask: 0; dwVisibleMask: 0; dwDamageMask: 0; // no layer, visible, damage masks ); var pixelFormat:integer; begin pixelFormat := ChoosePixelFormat(DC, @pfd); if (pixelFormat = 0) then exit; if (SetPixelFormat(DC, pixelFormat, @pfd) <> TRUE) then exit; end; procedure TGLPanel.init(); begin glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glViewport(0,0,self.width,self.height); glMatrixMode(GL_PROJECTION); glEnable(GL_TEXTURE_2D); //and very important, ENABLE TEXTURES!!! (new) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_BLEND); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); //glEnable(GL_LIGHT1); glLoadIdentity; gluPerspective( 45, self.width/self.height,1, 10); glMatrixMode(GL_MODELVIEW); glLoadIdentity; end; constructor TGLPanel.Create(AOwner: TComponent); begin inherited; Parent := (AOwner AS TWinControl); width:=parent.width; height:=parent.height; GLTimer:=TTimer.Create(parent); GLTimer.Interval:=ROTATION_TIMER_INTERVAL;; end; procedure TGLPanel.Resize; var lastrotation : integer; a,b,c,d : TGL3DCoord; vp : array [0..3] of GLint; begin DC:=GetDC(Handle); //if not assigned(ControlSet) then ControlSet.Free; inherited; SetupPixelFormat(DC); RC:=wglCreateContext(DC); //makes OpenGL window out of DC wglMakeCurrent(DC, RC); //makes OpenGL window active init; if not assigned(ControlSet) then createControls; lastrotation:=currentrotation; currentrotation:=0; draw; titles[0].realworldwidth:=round(getRealWorldPos(titles[0].Vertices.v3).x-getRealWorldPos(titles[0].Vertices.v1).x); titles[0].realworldheight:=round(getRealWorldPos(titles[0].Vertices.v1).y-getRealWorldPos(titles[0].Vertices.v3).y); titles[1].realworldwidth:=titles[0].realworldwidth; titles[1].realworldheight:=titles[0].realworldheight; titles[2].realworldwidth:=titles[0].realworldwidth; titles[2].realworldheight:=titles[0].realworldheight; titles[3].realworldwidth:=titles[0].realworldwidth; titles[3].realworldheight:=titles[0].realworldheight; currentrotation:=lastrotation; ControlSet.processcontrols(EVENT_RESIZE); InvalidateRgn(self.handle,0,true); glGetIntegerv(GL_VIEWPORT, @vp[0]); with Background[0] do begin with Vertices do begin c.x:=0; c.y:=0; c.z:=-2; d:=getRealWorldPos(c); a:=getGLPosZ(0,0,d.z); b:=getGLPosZ(width,height,d.z); v1:=gl3d(a.x,b.y,c.z); v2:=gl3d(b.x,b.y,c.z); v3:=gl3d(b.x,a.y,c.z); v4:=gl3d(a.x,a.y,c.z); end; end; end; procedure TGLPanel.Draw; var dir : integer; key : word; const light_diffuse : array[0..3] of GLFloat = ( 1.5, 1.5, 1.5, 0.9 ); light_position : array[0..3] of GLFloat = ( 1.5, 1.5, 1.5, 1 ); //light_ambient : array[0..3] of GLFloat = ( 1, 1, 1,1 ); //light_position2 : array[0..3] of GLFloat = ( 0, 0, 20, 1 ); begin if not assigned(Background[0]) then exit; dir:=0; glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glloadidentity(); //if BackGroundImageWidth<>0 then glDrawPixels(BackGroundImageWidth,BackGroundImageHeight,GL_BGRA_EXT, GL_UNSIGNED_BYTE, @BackgroundImage[0]); glLightfv(GL_LIGHT0, GL_DIFFUSE, @light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, @light_position); //glLightfv(GL_LIGHT1, GL_POSITION, @light_position2); //glLightfv(GL_LIGHT1, GL_AMBIENT, @light_ambient); glloadidentity(); gluLookAt(0.0, 0, 5.75, { eye is at (0,0,5)} 0.0, 0.0, 0.0, {center is at (0,0,0)} 0.0, 1.0, 0); {up is in positive Y direction} glRotatef(0, 0.0, 1.0, 0.0); BackGround[0].Paint; //Arrows[0].Paint; //Arrows[1].Paint; currentrotation:=currentrotation+rotation; if currentrotation>359 then begin currentrotation:=currentrotation-360; bnd:=0; end; if currentrotation<0 then begin currentrotation:=360+currentrotation; bnd:=360; end; if (rotation<0) then dir:=-1; if (rotation>0) then dir:=1; if (((currentrotation-bnd)>0 ) and (dir=1)) or (((currentrotation-bnd)<0 ) and (dir=-1)) then begin if dir=1 then jukebox.drawalbum3D(currentalbum,1); if dir=1 then bnd:=currentrotation+90 else bnd:=currentrotation-90; if dir=-1 then currentalbum:=currentalbum+1; if dir=1 then currentalbum:=currentalbum-1; if currentalbum>jalbumcount-1 then currentalbum:=1; if currentalbum<=0 then currentalbum:=jalbumcount-1; if DEBUGON then outputdebugstring(pansichar(inttostr(currentalbum)+' '+inttostr(bnd)+' '+inttostr(currentrotation))); if dir=-1 then jukebox.drawalbum3D(currentalbum,-1); if config.wraponunderscore=true then begin if (currentalbum<= mainform.albumlist.items.count) then if length(mainform.albumlist.items[currentalbum])>0 then if (mainform.albumlist.items[currentalbum][1]='_') and (dir=-1) then begin key:=65; jukebox.FormKeydown(self,key,[]); end; if (currentalbum<= mainform.albumlist.items.count) then if length(mainform.albumlist.items[currentalbum])>0 then if (mainform.albumlist.items[currentalbum][1]='_') and (dir=1) then begin key:=90; jukebox.FormKeydown(self,key,[]); end; end; prev_dir:=dir; end; // if ((currentrotation-bnd)=-1) then begin // jukebox.drawalbum3D(currentalbum,-1); // bnd:=currentrotation; // currentalbum:=currentalbum-1; // if currentalbum<1 then currentalbum:=jalbumcount-1; // outputdebugstring('-90'); // end; lastrotation:=rotation; glRotatef(currentrotation, 0, 1.0, 0.0); // caption:=inttostr(currentrotation)+' - '+inttostr(rotation)+' '; ControlSet.Draw; glPushMatrix; SwapBuffers(wglGetCurrentDC); end; procedure TGLPanel.MouseMove(Shift: TShiftState; X, Y: Integer); begin if moveinprogress=true then exit; inherited; if starttime=0 then if (controlset.processcontrols(EVENT_MOUSEMOVE)=RESULT_TRUE) then begin;rotation:=0;draw;exit;end; endtime:=gettickcount; endpoint:=x; end; procedure TGLPanel.MouseUp( Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var res : integer; begin if moveinprogress=true then exit; inherited; if starttime=0 then begin res:=controlset.processcontrols(EVENT_MOUSEUP); if res=RESULT_TRUE then begin;rotation:=0;draw;exit;end; if res=RESULT_FALSE_BUT_NEEDS_REDRAW then begin rotation:=0; draw; end; end; starttime:=0; //lastrotation:=rotation; GLTimer.enabled:=false; GLTimer.Interval:=ROTATION_TIMER_INTERVAL; GLTimer.OnTimer:=GLTimerTimer; GLTimerTimer(self); //GLTimer.enabled:=true; end; {procedure TGLPanel.Close(Sender: TObject; var Action: TCloseAction); begin if RC<>0 then begin wglMakeCurrent (0,0); wglDeleteContext(rc); end; // if DC<>0 then DeleteDC(dc); end; } procedure TGLPanel.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin jukebox.closepanels; if moveinprogress=true then exit; inherited; if (controlset.processcontrols(EVENT_MOUSEDOWN)=RESULT_TRUE) then begin;rotation:=0;draw;exit;end; gltimer.Enabled:=true; starttime:=gettickcount; startpoint:=x; end; procedure TGLPanel.Paint; begin inherited; draw; end; procedure TGLPanel.SetLbEnabled(var l : tglListbox); begin Titles[0].enabled:=false; Titles[1].enabled:=false; Titles[2].enabled:=false; Titles[3].enabled:=false; l.enabled:=true; end; procedure TGLPanel.doautorotation(stop : integer;rot : integer;enable : TGLListbox); var n : integer; t : integer; begin rotation:=rot; moveinprogress:=true; t:=5; if rotation=1 then begin rotation:=t; currentrotation:=currentrotation+(t-((currentrotation) mod t)); n:=currentrotation; while n<= stop do begin n:=n+t; draw; application.ProcessMessages; end; end else begin t:=-5; rotation:=t; currentrotation:=currentrotation+(t-((currentrotation) mod t)); n:=currentrotation; while n>= stop do begin n:=n+t; draw; application.ProcessMessages; end; end; setlbenabled(enable); moveinprogress:=false; rotation:=0; end; procedure TGLPanel.GLTimerTimer(Sender: TObject); var distance : integer; range : double; begin if starttime>0 then begin //if GLTimer.Interval>10 then GLTimer.Interval:=GLTimer.Interval-1; distance:=(endpoint - startpoint); //time:=endtime-starttime; range:=10 / width; if distance=0 then begin rotation:=0; // lastrotation:=0; exit; end; rotation:=round(distance*range); if rotation=0 then exit; draw; end; if ((starttime=0) and (sender=self)) then begin if (rotation>0) then begin if ((currentrotation>0) and (currentrotation<90)) then begin doautorotation(89,1,Titles[3]);exit;end; if ((currentrotation>90) and (currentrotation<180)) then begin doautorotation(179,1,Titles[2]);exit;end; if ((currentrotation>180) and (currentrotation<270)) then begin doautorotation(269,1,Titles[1]);exit;end; if ((currentrotation>270) and (currentrotation<360)) then begin doautorotation(359,1,Titles[0]);exit;end; end; if (rotation<0) then begin if ((currentrotation>270) and (currentrotation<360)) then begin doautorotation(271,-1,Titles[1]);exit;end; if ((currentrotation>180) and (currentrotation<270)) then begin doautorotation(181,-1,Titles[2]);exit;end; if ((currentrotation>90) and (currentrotation<180)) then begin doautorotation(91,-1,Titles[3]);exit;end; if ((currentrotation>0) and (currentrotation<90)) then begin doautorotation(1,-1,Titles[0]);exit;end; rotation:=0; //lastrotation:=0; end; end; end; procedure TGLPanel.NoAlbums; begin Artwork[0].bitmap:=nil; Artwork[1].bitmap:=nil; Artwork[2].bitmap:=nil; Artwork[3].bitmap:=nil; Titles[0].items.clear; Titles[1].items.clear; Titles[2].items.clear; Titles[3].items.clear; end; end.