From 9975f56cded5f6251d0110238fd97b7ee7ccae31 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Wed, 18 Nov 2009 14:42:34 +0000 Subject: some changes on mousesupport - you can click on the whole area of a button after fading - options on selects can be changed by clicking on the arrows - fix mouse parsing at the screensong extensions git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1950 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/menu/UMenu.pas | 79 ++++++++++++++++++++++++++----------------- src/menu/UMenuButton.pas | 48 +++++++++++++++++++++++++- src/menu/UMenuInteract.pas | 9 +++++ src/menu/UMenuSelectSlide.pas | 33 +++++++++++++++++- src/screens/UScreenSong.pas | 35 +++++++++++++------ 5 files changed, 160 insertions(+), 44 deletions(-) diff --git a/src/menu/UMenu.pas b/src/menu/UMenu.pas index 7979e28e..659d4213 100644 --- a/src/menu/UMenu.pas +++ b/src/menu/UMenu.pas @@ -147,7 +147,7 @@ type function Draw: boolean; virtual; function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown : boolean): boolean; virtual; function ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean; virtual; - function InRegion(X1, Y1, W, H, X, Y: real): boolean; + function InRegion(X, Y: real; A: TMouseOverRect): boolean; function InteractAt(X, Y: real): integer; function CollectionAt(X, Y: real): integer; procedure OnShow; virtual; @@ -1629,6 +1629,7 @@ end; function TMenu.ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean; var nBut: integer; + Action: TMouseClickAction; begin //default mouse parsing: clicking generates return keypress, // mousewheel selects in select slide @@ -1647,30 +1648,45 @@ begin //select on mouse-over if nBut <> Interaction then SetInteraction(nBut); - if (MouseButton = SDL_BUTTON_LEFT) and BtnDown then - begin - //click button - Result:=ParseInput(SDLK_RETURN, 0, true); - end; - if (Interactions[nBut].Typ = iSelectS) then + + Action := maNone; + + if (BtnDown) then begin - //forward/backward in select slide with mousewheel - if (MouseButton = SDL_BUTTON_WHEELDOWN) and BtnDown then - begin - ParseInput(SDLK_RIGHT, 0, true); - end; - if (MouseButton = SDL_BUTTON_WHEELUP) and BtnDown then + if (MouseButton = SDL_BUTTON_LEFT) then begin - ParseInput(SDLK_LEFT, 0, true); + //click button or SelectS + if (Interactions[nBut].Typ = iSelectS) then + Action := SelectsS[Interactions[nBut].Num].OnClick((X / Screen.w) * RenderW, (Y / Screen.h) * RenderH) + else + Action := maReturn; + end + else if (MouseButton = SDL_BUTTON_WHEELDOWN) then + begin //forward on select slide with mousewheel + if (Interactions[nBut].Typ = iSelectS) then + Action := maRight; + end + else if (MouseButton = SDL_BUTTON_WHEELUP) then + begin //backward on select slide with mousewheel + if (Interactions[nBut].Typ = iSelectS) then + Action := maLeft; end; end; + + // do the action we have to do ;) + case Action of + maReturn: Result := ParseInput(SDLK_RETURN, 0, true); + maLeft: Result := ParseInput(SDLK_LEFT, 0, true); + maRight: Result := ParseInput(SDLK_RIGHT, 0, true); + end; end else begin nBut := CollectionAt(X, Y); - if nBut >= 0 then + if (nBut >= 0) and (not ButtonCollection[nBut].Selected) then begin - // if over button collection, select first child but don't allow click + // if over button collection, that is not already selected + // -> select first child but don't allow click nBut := ButtonCollection[nBut].FirstChild - 1; if nBut <> Interaction then SetInteraction(nBut); @@ -1678,15 +1694,14 @@ begin end; end; -function TMenu.InRegion(X1, Y1, W, H, X, Y: real): boolean; +function TMenu.InRegion(X, Y: real; A: TMouseOverRect): boolean; begin - Result := false; - X1 := X1 * Screen.w / 800; - W := W * Screen.w / 800; - Y1 := Y1 * Screen.h / 600; - H := H * Screen.h / 600; - if (X >= X1) and (X <= X1 + W) and (Y >= Y1) and (Y <= Y1 + H) then - Result := true; + // transfer mousecords to the 800x600 raster we use to draw + X := (X / Screen.w) * RenderW; + Y := (Y / Screen.h) * RenderH; + + // check whether A contains X and Y + Result := (X >= A.X) and (X <= A.X + A.W) and (Y >= A.Y) and (Y <= A.Y + A.H); end; //takes x,y coordinates and returns the interaction number @@ -1699,20 +1714,22 @@ begin for i := Low(Interactions) to High(Interactions) do begin case Interactions[i].Typ of - iButton: if InRegion(Button[Interactions[i].Num].X, Button[Interactions[i].Num].Y, Button[Interactions[i].Num].W, Button[Interactions[i].Num].H, X, Y) and + iButton: + if InRegion(X, Y, Button[Interactions[i].Num].GetMouseOverArea) and Button[Interactions[i].Num].Visible then - begin + begin Result:=i; exit; end; - iBCollectionChild: if InRegion(Button[Interactions[i].Num].X, Button[Interactions[i].Num].Y, Button[Interactions[i].Num].W, Button[Interactions[i].Num].H, X, Y) then + iBCollectionChild: + if InRegion(X, Y, Button[Interactions[i].Num].GetMouseOverArea) then begin Result:=i; exit; end; - iSelectS: if InRegion(SelectSs[Interactions[i].Num].X, SelectSs[Interactions[i].Num].Y, SelectSs[Interactions[i].Num].W, SelectSs[Interactions[i].Num].H, X, Y) or - InRegion(SelectSs[Interactions[i].Num].TextureSBG.X, SelectSs[Interactions[i].Num].TextureSBG.Y, SelectSs[Interactions[i].Num].TextureSBG.W, SelectSs[Interactions[i].Num].TextureSBG.H, X, Y) then - begin + iSelectS: + if InRegion(X, Y, SelectSs[Interactions[i].Num].GetMouseOverArea) then + begin Result:=i; exit; end; @@ -1728,7 +1745,7 @@ begin Result := -1; for i:= Low(ButtonCollection) to High(ButtonCollection) do begin - if InRegion(ButtonCollection[i].X, ButtonCollection[i].Y, ButtonCollection[i].W, ButtonCollection[i].H, X, Y) and + if InRegion(X, Y, ButtonCollection[i].GetMouseOverArea) and ButtonCollection[i].Visible then begin Result:=i; diff --git a/src/menu/UMenuButton.pas b/src/menu/UMenuButton.pas index 923f0b14..868a86f3 100644 --- a/src/menu/UMenuButton.pas +++ b/src/menu/UMenuButton.pas @@ -38,7 +38,8 @@ uses UTexture, gl, UMenuText, - SDL; + SDL, + UMenuInteract; type CButton = class of TButton; @@ -116,6 +117,8 @@ type constructor Create(Textura: TTexture); overload; constructor Create(Textura, DSTexture: TTexture); overload; destructor Destroy; override; + + function GetMouseOverArea: TMouseOverRect; end; implementation @@ -529,6 +532,49 @@ begin end; end; +function TButton.GetMouseOverArea: TMouseOverRect; +begin + if (FadeTex.TexNum = 0) then + begin + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := Texture.W; + Result.H := Texture.H; + end + else + begin + case FadeTexPos of + 0: begin // fade tex on top + Result.X := Texture.X; + Result.Y := FadeTex.Y; + Result.W := Texture.W; + Result.H := FadeTex.H + Texture.H; + end; + + 1: begin // fade tex on left side + Result.X := FadeTex.X; + Result.Y := Texture.Y; + Result.W := FadeTex.W + Texture.W; + Result.H := Texture.H; + end; + + 2: begin // fade tex on bottom + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := Texture.W; + Result.H := FadeTex.H + Texture.H; + end; + + 3: begin // fade tex on right side + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := FadeTex.W + Texture.W; + Result.H := Texture.H; + end; + end; + end; +end; + destructor TButton.Destroy; begin diff --git a/src/menu/UMenuInteract.pas b/src/menu/UMenuInteract.pas index beb6bcef..7cb92025 100644 --- a/src/menu/UMenuInteract.pas +++ b/src/menu/UMenuInteract.pas @@ -39,6 +39,15 @@ type Num: integer; // number of this item in proper list like buttons, selects end; + { to handle the area where the mouse is over a control } + TMouseOverRect = record + X, Y: Real; + W, H: Real; + end; + + { to handle the on click action } + TMouseClickAction = (maNone, maReturn, maLeft, maRight); + implementation end. diff --git a/src/menu/UMenuSelectSlide.pas b/src/menu/UMenuSelectSlide.pas index 6bc824f4..11be4c2a 100644 --- a/src/menu/UMenuSelectSlide.pas +++ b/src/menu/UMenuSelectSlide.pas @@ -37,7 +37,8 @@ uses gl, TextGL, UMenuText, - UTexture; + UTexture, + UMenuInteract; type PSelectSlide = ^TSelectSlide; @@ -135,6 +136,9 @@ type //Automatically Generate Lines (Texts) procedure genLines; + + function GetMouseOverArea: TMouseOverRect; + function OnClick(X, Y: Real): TMouseClickAction; end; implementation @@ -405,4 +409,31 @@ begin end; end; +function TSelectSlide.GetMouseOverArea: TMouseOverRect; +begin + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := (TextureSBG.X + TextureSBG.W) - Result.X; + Result.H := Max(Texture.H, TextureSBG.H); +end; + +function TSelectSlide.OnClick(X, Y: Real): TMouseClickAction; + var + AreaW: Real; +begin + // default: press return on click + Result := maReturn; + + // use left sides to inc or dec selection by click + AreaW := TextureSbg.W / 20; + + if (Y >= TextureSBG.Y) and (Y <= TextureSBG.Y + TextureSBG.H) then + begin + if (X >= TextureSBG.X) and (X <= TextureSBG.X + AreaW) then + Result := maLeft // hit left area + else if (X >= TextureSBG.X + TextureSBG.W - AreaW) and (X <= TextureSBG.X + TextureSBG.W) then + Result := maRight; // hit right area + end; +end; + end. diff --git a/src/screens/UScreenSong.pas b/src/screens/UScreenSong.pas index ff2ab201..e74ea75d 100644 --- a/src/screens/UScreenSong.pas +++ b/src/screens/UScreenSong.pas @@ -755,20 +755,33 @@ function TScreenSong.ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: in begin Result := true; - if RightMbESC and (MouseButton = SDL_BUTTON_RIGHT) and BtnDown then - //if RightMbESC is set, send ESC keypress - Result:=ParseInput(SDLK_ESCAPE, 0, true); + if (ScreenSongMenu.Visible) then + begin + Result := ScreenSongMenu.ParseMouse(MouseButton, BtnDown, X, Y); + exit; + end + else if (ScreenSongJumpTo.Visible) then + begin + Result := ScreenSongJumpTo.ParseMouse(MouseButton, BtnDown, X, Y); + exit; + end + else // no extension visible + begin + if RightMbESC and (MouseButton = SDL_BUTTON_RIGHT) and BtnDown then + //if RightMbESC is set, send ESC keypress + Result:=ParseInput(SDLK_ESCAPE, 0, true); - //song scrolling with mousewheel - if (MouseButton = SDL_BUTTON_WHEELDOWN) and BtnDown then - ParseInput(SDLK_RIGHT, 0, true); + //song scrolling with mousewheel + if (MouseButton = SDL_BUTTON_WHEELDOWN) and BtnDown then + ParseInput(SDLK_RIGHT, 0, true); - if (MouseButton = SDL_BUTTON_WHEELUP) and BtnDown then - ParseInput(SDLK_LEFT, 0, true); + if (MouseButton = SDL_BUTTON_WHEELUP) and BtnDown then + ParseInput(SDLK_LEFT, 0, true); - //LMB anywhere starts - if (MouseButton = SDL_BUTTON_LEFT) and BtnDown then - ParseInput(SDLK_RETURN, 0, true); + //LMB anywhere starts + if (MouseButton = SDL_BUTTON_LEFT) and BtnDown then + ParseInput(SDLK_RETURN, 0, true); + end; end; constructor TScreenSong.Create; -- cgit v1.2.3