Creating a custom slider?

Does anybody know how I’d go about creating a custom slider with 2D Shapes without using any addons?

I had the idea of using the mouseDragged function and finding the coords of the circle for the slider value and moving it on click, but all it does is move to the right, I can’t move it back and I am unsure of how to stop it from moving outside of the shape it’s layered over.

void ofApp::mouseDragged(int x, int y, int button) {
	if ((x >= sliderX && x <= sliderX + 128) && (y >= sliderY && y <= sliderY + 128)) {
		sliderX = x;
	}
}

Thanks

1 Like

Use ofDrawRectRounded and fill it with any color. On mousemoved check if mouse is inside rectangle(slider) and set x or y of slider value based ob your x or y mouse position.

1 Like

Okay, I’ve got it working so it won’t go over the length of the rectangle but it still only moves to the right?

Hi, the ofRectangle class has everything you need to do so.
it has a inside(x, y) function that returns true if the coordinates you pass are insde of it or not.
You can either extend ofRectangle or make a new class that holds one. Or for testing you can simply do it all within ofApp.

it would be something like

ofApp.h

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void draw();

		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);

		
	
	bool bDragging = false;
	
	glm::vec2 offset;
	ofRectangle slider;
	ofRectangle container;
	
};

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
	
	// set the slider and container to the desired sizes
	slider.set(200, 200, 300, 20);
	container.set(20, 200, ofGetWidth() - 40, 20);
	
}
//--------------------------------------------------------------
void ofApp::draw(){

	ofSetColor(ofColor::white);
	ofNoFill();
	ofDrawRectangle(container);
	
	
	ofSetColor(120);
	ofFill();
	ofDrawRectangle(slider);
	
	if(slider.inside(ofGetMouseX(), ofGetMouseY()))
	{
		/// if the mouse is over just draw a highlight
		ofSetColor(ofColor::yellow);
		ofNoFill();
		ofDrawRectangle(slider);
		
	}
	
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){
	if(bDragging)
	{
		slider.x = x - offset.x;
		
		// make sure it stays withing bounds
		if(slider.x < container.x)
		{
			slider.x = container.x;
		}
		if(slider.getMaxX() > container.getMaxX())
		{
			slider.x = container.getMaxX() - slider.width;
		}
	}
}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

	if(slider.inside(x,y))
	{
		bDragging = true;
		offset = glm::vec2(x,y) - slider.getPosition();
		
	}
}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){
	bDragging = false;
}
3 Likes

That looks great, thank you. To assign it to a variable I have taken slider.x and assigned it to an ofMap function to emulate a slider.

Right. you need to take into account the width of the slider for this calculations, so when it is at it´s maximum position you get the desired maximum value