This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/wwui/sliderctrl.cpp

441 lines
10 KiB
C++

/*
** Command & Conquer Renegade(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Combat *
* *
* $Archive:: /Commando/Code/wwui/sliderctrl.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 1/09/02 2:36p $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
// Disable warning about exception handling not being enabled. It's used as part of STL - in a part of STL we don't use.
#pragma warning(disable : 4530)
#include "sliderctrl.h"
#include "assetmgr.h"
#include "refcount.h"
#include "mousemgr.h"
#include "ww3d.h"
#include "dialogmgr.h"
#include "dialogbase.h"
#include "stylemgr.h"
////////////////////////////////////////////////////////////////
// Local constants
////////////////////////////////////////////////////////////////
const float BAR_HEIGHT = 8.0F;
////////////////////////////////////////////////////////////////
//
// SliderCtrlClass
//
////////////////////////////////////////////////////////////////
SliderCtrlClass::SliderCtrlClass (void) :
MinPos (0),
MaxPos (100),
CurrPos (0),
IsDragging (false)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// ~SliderCtrlClass
//
////////////////////////////////////////////////////////////////
SliderCtrlClass::~SliderCtrlClass (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Create_Control_Renderer
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::Create_Control_Renderer (void)
{
Render2DClass &renderer = ControlRenderer;
//
// Configure this renderer
//
renderer.Reset ();
renderer.Enable_Texturing (false);
renderer.Set_Coordinate_Range (Render2DClass::Get_Screen_Resolution());
//
// Determine which color to draw the outline in
//
int color = StyleMgrClass::Get_Line_Color ();
int bkcolor = StyleMgrClass::Get_Bk_Color ();
if (IsEnabled == false) {
color = StyleMgrClass::Get_Disabled_Line_Color ();
bkcolor = StyleMgrClass::Get_Disabled_Bk_Color ();
}
//
// Calculate the thumb's position
//
float percent = float(CurrPos - MinPos) / float(MaxPos - MinPos);
int thumb_height = ClientRect.Height () - 2;
int thumb_width = thumb_height / 2;
//
// Calculate the rectangle for the thumb
//
RectClass rect;
rect.Left = int (ClientRect.Left + (ClientRect.Width () * percent) - (thumb_width * 0.5F));
rect.Right = rect.Left + thumb_width;
rect.Top = int(ClientRect.Top + (ClientRect.Height () / 2) - (thumb_height / 2));
rect.Bottom = int(ClientRect.Top + (ClientRect.Height () / 2) + (thumb_height / 2));
//
// Draw the thumb
//
renderer.Add_Rect (rect, 1.0F, color, HasFocus ? color : bkcolor);
//
// Determine what height to use for the bar
//
float bar_height = BAR_HEIGHT * StyleMgrClass::Get_Y_Scale ();
//
// Calculate the rectangle for the control
//
RectClass rect1;
RectClass rect2;
rect1.Left = ClientRect.Left;
rect1.Right = rect.Left;
rect2.Left = rect.Right;
rect2.Right = ClientRect.Right;
rect1.Top = int(ClientRect.Top + (ClientRect.Height () / 2) - (bar_height / 2));
rect1.Bottom = int(ClientRect.Top + (ClientRect.Height () / 2) + (bar_height / 2));
rect2.Top = rect1.Top;
rect2.Bottom = rect1.Bottom;
//
// Draw the bar in two sections
//
if (rect1.Right > rect1.Left) {
renderer.Add_Rect (rect1, 1.0F, color, bkcolor);
}
if (rect2.Right > rect2.Left) {
renderer.Add_Rect (rect2, 1.0F, color, bkcolor);
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Cursor
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::On_Set_Cursor (const Vector2 &mouse_pos)
{
//
// Change the mouse cursor
//
MouseMgrClass::Set_Cursor (MouseMgrClass::CURSOR_ACTION);
return ;
}
////////////////////////////////////////////////////////////////
//
// Update_Client_Rect
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::Update_Client_Rect (void)
{
//
// Set the client area
//
ClientRect = Rect;
Set_Dirty ();
return ;
}
////////////////////////////////////////////////////////////////
//
// Render
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::Render (void)
{
//
// Recreate the renderers (if necessary)
//
if (IsDirty) {
Create_Control_Renderer ();
}
//
// Render the background and text for the current state
//
ControlRenderer.Render ();
DialogControlClass::Render ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Down
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::On_LButton_Down (const Vector2 &mouse_pos)
{
Set_Capture ();
IsDragging = true;
//
// Snap the slider to the mouse position
//
Set_Pos (Slider_Pos_From_Mouse_Pos (mouse_pos));
return ;
}
////////////////////////////////////////////////////////////////
//
// On_LButton_Up
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::On_LButton_Up (const Vector2 &mouse_pos)
{
Release_Capture ();
IsDragging = false;
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Mouse_Move
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::On_Mouse_Move (const Vector2 &mouse_pos)
{
if (IsDragging) {
Set_Pos (Slider_Pos_From_Mouse_Pos (mouse_pos));
}
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Set_Focus
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::On_Set_Focus (void)
{
Set_Dirty ();
DialogControlClass::On_Set_Focus ();
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Kill_Focus
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::On_Kill_Focus (DialogControlClass *focus)
{
IsDragging = false;
Set_Dirty ();
DialogControlClass::On_Kill_Focus (focus);
return ;
}
////////////////////////////////////////////////////////////////
//
// On_Key_Down
//
////////////////////////////////////////////////////////////////
bool
SliderCtrlClass::On_Key_Down (uint32 key_id, uint32 key_data)
{
bool handled = true;
switch (key_id)
{
case VK_DOWN:
case VK_LEFT:
Set_Pos (CurrPos - 1);
break;
case VK_UP:
case VK_RIGHT:
Set_Pos (CurrPos + 1);
break;
case VK_HOME:
Set_Pos (MinPos);
break;
case VK_END:
Set_Pos (MaxPos);
break;
default:
handled = false;
break;
}
return handled;
}
////////////////////////////////////////////////////////////////
//
// On_Create
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::On_Create (void)
{
return ;
}
////////////////////////////////////////////////////////////////
//
// Slider_Pos_From_Mouse_Pos
//
////////////////////////////////////////////////////////////////
int
SliderCtrlClass::Slider_Pos_From_Mouse_Pos (const Vector2 &mouse_pos)
{
int retval = 0;
if (mouse_pos.X < ClientRect.Left) {
//
// Mouse is to the left of the control
//
retval = MinPos;
} else if (mouse_pos.X >= ClientRect.Right) {
//
// Mouse is to the right of the control
//
retval = MaxPos;
} else {
int thumb_height = ClientRect.Height () - 2;
int thumb_width = thumb_height / 2;
//
// Calculate where in the range the mouse is and return its position
//
float percent = (mouse_pos.X - (ClientRect.Left - (thumb_width * 0.5F))) / ClientRect.Width ();
retval = MinPos + int(percent * (MaxPos - MinPos)) ;
}
return retval;
}
////////////////////////////////////////////////////////////////
//
// Set_Range
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::Set_Range (int range_min, int range_max)
{
MinPos = range_min;
MaxPos = range_max;
Set_Pos (MinPos);
return ;
}
////////////////////////////////////////////////////////////////
//
// Set_Pos
//
////////////////////////////////////////////////////////////////
void
SliderCtrlClass::Set_Pos (int pos, bool send_notification)
{
//
// Bound the new position
//
if (pos < MinPos) {
pos = MinPos;
} else if (pos > MaxPos) {
pos = MaxPos;
}
//
// Update the current position
//
if (pos != CurrPos) {
CurrPos = pos;
Set_Dirty ();
//
// Notify the advise sinks if necessary
//
if (send_notification) {
ADVISE_NOTIFY (On_SliderCtrl_Pos_Changed (this, Get_ID (), CurrPos));
}
}
return ;
}