Files
CMLeonOS/Gui/UILib/RangeSlider.cs

221 lines
6.0 KiB
C#
Raw Normal View History

2026-03-08 20:22:53 +08:00
// The CMLeonOS Project (https://github.com/Leonmmcoset/CMLeonOS)
// Copyright (C) 2025-present LeonOS 2 Developer Team
//
// 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 <https://www.gnu.org/licenses/>.
2026-03-01 17:03:49 +08:00
using Cosmos.System;
using CMLeonOS;
using CMLeonOS.Gui.SmoothMono;
using CMLeonOS.Utils;
using System;
using System.Drawing;
namespace CMLeonOS.Gui.UILib
{
internal class RangeSlider : Control
{
public RangeSlider(Window parent, int x, int y, int width, int height) : base(parent, x, y, width, height)
{
OnDown = RangeSliderDown;
}
public RangeSlider(Window parent, int x, int y, int width, int height, float min, float value, float max) : base(parent, x, y, width, height)
{
OnDown = RangeSliderDown;
_minimum = min;
_value = value;
_maximum = max;
Render();
}
2026-03-23 21:34:21 +08:00
private Color _background = UITheme.Surface;
2026-03-01 17:03:49 +08:00
internal Color Background
{
get
{
return _background;
}
set
{
_background = value;
Render();
}
}
2026-03-23 21:34:21 +08:00
private Color _foreground = UITheme.TextSecondary;
2026-03-01 17:03:49 +08:00
internal Color Foreground
{
get
{
return _foreground;
}
set
{
_foreground = value;
Render();
}
}
private float _minimum = 0;
internal float Minimum
{
get
{
return _minimum;
}
set
{
if (_minimum != value)
{
_minimum = value;
Render();
}
}
}
private float _value = 50;
internal float Value
{
get
{
return _value;
}
set
{
if (_value != value)
{
_value = value;
Render();
Changed?.Invoke(value);
}
}
}
private float _maximum = 100;
internal float Maximum
{
get
{
return _maximum;
}
set
{
if (_maximum != value)
{
_maximum = value;
Render();
}
}
}
private bool _rangeLabels = true;
internal bool RangeLabels
{
get
{
return _rangeLabels;
}
set
{
if (_rangeLabels != value)
{
_rangeLabels = value;
Render();
}
}
}
internal Action<float> Changed { get; set; }
private bool held = false;
2026-03-23 21:34:21 +08:00
private static int slotHeight = 4;
private static int sliderHeight = 16;
private static int sliderWidth = 8;
2026-03-01 17:03:49 +08:00
private void RangeSliderDown(int x, int y)
{
held = true;
Render();
}
internal override void Render()
{
if (held && MouseManager.MouseState != MouseState.Left)
{
held = false;
}
if (held)
{
float relativeX = (float)(MouseManager.X - ScreenX);
float clamped = Math.Clamp(relativeX, 0, Width - sliderWidth);
//DrawString(clamped.ToString(), Color.Red, 0, 0);
Value = (float)clamped.Map(0, Width - sliderWidth, (float)_minimum, (float)_maximum);
WM.UpdateQueue.Enqueue(this);
}
Clear(Background);
int slotY;
int sliderY;
if (_rangeLabels)
{
slotY = (sliderHeight / 2) - (slotHeight / 2);
sliderY = 0;
}
else
{
slotY = (Height / 2) - (slotHeight / 2);
sliderY = (Height / 2) - (sliderHeight / 2);
}
// Slot
2026-03-23 21:34:21 +08:00
DrawFilledRectangle(0, slotY, Width, slotHeight, UITheme.SurfaceBorder);
int fillWidth = (int)(_value.Map((float)_minimum, (float)_maximum, 0, Width - sliderWidth)) + (sliderWidth / 2);
DrawFilledRectangle(0, slotY, Math.Max(0, fillWidth), slotHeight, UITheme.AccentLight);
2026-03-01 17:03:49 +08:00
// Slider
DrawFilledRectangle(
(int)(_value.Map((float)_minimum, (float)_maximum, 0, Width - sliderWidth)),
sliderY,
sliderWidth,
sliderHeight,
2026-03-23 21:34:21 +08:00
held ? UITheme.AccentDark : UITheme.Accent
);
DrawRectangle(
(int)(_value.Map((float)_minimum, (float)_maximum, 0, Width - sliderWidth)),
sliderY,
sliderWidth,
sliderHeight,
UITheme.AccentDark
2026-03-01 17:03:49 +08:00
);
if (_rangeLabels)
{
DrawString(_minimum.ToString(), Foreground, 0, Height - FontData.Height);
DrawString(_maximum.ToString(), Foreground, Width - (FontData.Width * _maximum.ToString().Length), Height - FontData.Height);
}
WM.Update(this);
}
}
}