hyprlock icon indicating copy to clipboard operation
hyprlock copied to clipboard

widgets: add progress-bar widget implementation

Open Memoraike opened this issue 11 months ago • 3 comments

Adds a new widget type CScale. With this widget and functionality in https://github.com/hyprwm/hyprlock/pull/653 it is now possible to implement such things:

Details

image

  • config: introduce special category and config values for scale
  • renderer: integrate scale widget into widget creation
  • scale: implement CScale class with drawing and timer functionality

Memoraike avatar Jan 24 '25 03:01 Memoraike

I think 'progress-bar"/CProgressBar would be a better name.

Is the duration purely handled by the animation speed? How do you sync the song's progress with the progress of the shape widget?

PointerDilemma avatar Jan 24 '25 16:01 PointerDilemma

Showcase:

music-info
#!/bin/bash

## Get data
COVER="/tmp/music_cover.png"
MUSIC_DIR="$HOME/Music"

## Get status
get_status() {
	if [[ "$(playerctl status 2>/dev/null)" == "Playing" ]]; then
		echo " "
	else
		echo " "
	fi
}

## Get song
get_song() {
	song=$(playerctl metadata title 2>/dev/null)
	if [[ -z "$song" ]]; then
		echo "-"
	else
		echo "$song"
	fi
}

## Get artist
get_artist() {
	artist=$(playerctl metadata artist 2>/dev/null)
	if [[ -z "$artist" ]]; then
		echo "-"
	else
		echo "$artist"
	fi
}

## Get time
get_time() {
	position=$(playerctl position 2>/dev/null | awk '{print int($1/60) ":" int($1%60)}')
	duration=$(playerctl metadata mpris:length 2>/dev/null | awk '{print int($1/60000000) ":" int(($1/1000000)%60)}')
	if [[ -z "$position" || -z "$duration" ]]; then
		echo "0:00"
	else
		echo "$position/$duration"
	fi
}

get_ctime() {
	position=$(playerctl position 2>/dev/null)
	if [[ -z "$position" ]]; then
		echo "0:00"
	else
		echo "$(date -d@$position -u +%M:%S)"
	fi
}

get_ttime() {
	duration=$(playerctl metadata mpris:length 2>/dev/null)
	if [[ -z "$duration" ]]; then
		echo "0:00"
	else
		echo "$(date -d@$(($duration / 1000000)) -u +%M:%S)"
	fi
}

## Get cover
get_cover() {
	album_art=$(playerctl metadata mpris:artUrl 2>/dev/null | sed 's/^file:\/\///')
	if [[ -n "$album_art" && -f "$album_art" ]]; then
		magick "$album_art" -resize 120x120 "$COVER"
		echo "$COVER"
	else
		echo "images/music.png"
	fi
}

## Get progress
get_progress() {
	position=$(playerctl position 2>/dev/null)
	duration=$(playerctl metadata mpris:length 2>/dev/null)

	if [[ -z "$position" || -z "$duration" ]]; then
		echo "0"
		return
	fi

	position_int=$(printf "%.0f" "$position")
	duration_int=$(printf "%.0f" "$(echo "$duration / 1000000" | bc -l)")

	if [[ -z "$position_int" || -z "$duration_int" || "$duration_int" -eq 0 ]]; then
		echo "0"
	else
		progress=$((100 * position_int / duration_int))
		echo "$progress"
	fi
}

## Execute accordingly
if [[ "$1" == "--song" ]]; then
	get_song
elif [[ "$1" == "--artist" ]]; then
	get_artist
elif [[ "$1" == "--status" ]]; then
	get_status
elif [[ "$1" == "--time" ]]; then
	get_time
elif [[ "$1" == "--ctime" ]]; then
	get_ctime
elif [[ "$1" == "--ttime" ]]; then
	get_ttime
elif [[ "$1" == "--progress" ]]; then
  get_progress
elif [[ "$1" == "--cover" ]]; then
	get_cover
elif [[ "$1" == "--toggle" ]]; then
	playerctl play-pause
	get_cover
elif [[ "$1" == "--next" ]]; then
	playerctl next
	get_cover
elif [[ "$1" == "--prev" ]]; then
	playerctl previous
	get_cover
fi

hyprlock.conf
#region music player

shape {
    monitor =
    size = 480, 160
    color = rgba(0, 0, 0, 0.2)
    rounding = 12

    position = 0, 20
    halign = center
    valign = bottom
}

shape {
    monitor =
    size = 130, 130
    color = rgba(0, 0, 0, 0.2)
    rounding = 12

    position = -160, 35
    halign = center
    valign = bottom
}

image {
    monitor =
    path = images/music.png
    size = 120
    rounding = 12

    reload_time = 1
    reload_cmd = ~/.config/hypr/scripts/music-info --cover

    position = -160, 35
    halign = center
    valign = bottom
}

label {
    monitor =
    text = cmd[update:1000] ~/.config/hypr/scripts/music-info --song

    position = 70, 130
    halign = center
    valign = bottom
}

label {
    monitor =
    text = cmd[update:1000] ~/.config/hypr/scripts/music-info --artist
    font_size = 14

    position = 70, 105
    halign = center
    valign = bottom
}

label {
    monitor =
    text =  
    # font_size = 14
    onclick = playerctl previous

    position = 40, 65
    halign = center
    valign = bottom
}

label {
    monitor =
    text = cmd[update:1000] ~/.config/hypr/scripts/music-info --status
    font_size = 24
    onclick = playerctl play-pause

    position = 74, 60
    halign = center
    valign = bottom
}

label {
    monitor =
    text =  
    # font_size = 14
    onclick = playerctl next

    position = 105, 65
    halign = center
    valign = bottom
}

progressbar {
    monitor =
    size = 310, 10
    color = rgba(255, 0, 0, 1.0)
    rounding = 4
    background_color = rgba(50, 50, 50, 0.5)

    min = 0
    max = 100
    value = cmd[update:1000] ~/.config/hypr/scripts/music-info --progress

    position = -85, 40
    halign = center
    valign = bottom
}

#endregion

Memoraike avatar Jan 24 '25 18:01 Memoraike

I think 'progress-bar"/CProgressBar would be a better name.

Is the duration purely handled by the animation speed? How do you sync the song's progress with the progress of the shape widget?

I was inspired by eww, but I agree that CProgressBar current implementation describes it better.

Memoraike avatar Jan 24 '25 18:01 Memoraike