mirror of
https://github.com/Dummi26/musicdb.git
synced 2025-03-10 05:43:53 +01:00
add QueueMove operation
This commit is contained in:
parent
00b032aceb
commit
a2d24e780a
@ -365,6 +365,8 @@ impl Gui {
|
|||||||
| Command::QueueAdd(..)
|
| Command::QueueAdd(..)
|
||||||
| Command::QueueInsert(..)
|
| Command::QueueInsert(..)
|
||||||
| Command::QueueRemove(..)
|
| Command::QueueRemove(..)
|
||||||
|
| Command::QueueMove(..)
|
||||||
|
| Command::QueueMoveInto(..)
|
||||||
| Command::QueueGoto(..)
|
| Command::QueueGoto(..)
|
||||||
| Command::QueueShuffle(..)
|
| Command::QueueShuffle(..)
|
||||||
| Command::QueueSetShuffle(..)
|
| Command::QueueSetShuffle(..)
|
||||||
@ -1130,7 +1132,7 @@ pub enum Dragging {
|
|||||||
Artist(ArtistId),
|
Artist(ArtistId),
|
||||||
Album(AlbumId),
|
Album(AlbumId),
|
||||||
Song(SongId),
|
Song(SongId),
|
||||||
Queue(Queue),
|
Queue(Result<Queue, Vec<usize>>),
|
||||||
Queues(Vec<Queue>),
|
Queues(Vec<Queue>),
|
||||||
}
|
}
|
||||||
pub enum SpecificGuiElem {
|
pub enum SpecificGuiElem {
|
||||||
@ -1430,14 +1432,25 @@ impl WindowHandler<GuiEvent> for Gui {
|
|||||||
}
|
}
|
||||||
fn on_mouse_button_up(&mut self, helper: &mut WindowHelper<GuiEvent>, button: MouseButton) {
|
fn on_mouse_button_up(&mut self, helper: &mut WindowHelper<GuiEvent>, button: MouseButton) {
|
||||||
if self.dragging.is_some() {
|
if self.dragging.is_some() {
|
||||||
if let Some(a) = self.gui._release_drag(
|
let (dr, _) = self.dragging.take().unwrap();
|
||||||
&mut self.dragging.take().map(|v| v.0),
|
let mut opt = Some(dr);
|
||||||
self.mouse_pos.clone(),
|
if let Some(a) = self.gui._release_drag(&mut opt, self.mouse_pos.clone()) {
|
||||||
) {
|
|
||||||
for a in a {
|
for a in a {
|
||||||
self.exec_gui_action(a)
|
self.exec_gui_action(a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(dr) = opt {
|
||||||
|
match dr {
|
||||||
|
Dragging::Artist(_)
|
||||||
|
| Dragging::Album(_)
|
||||||
|
| Dragging::Song(_)
|
||||||
|
| Dragging::Queue(Ok(_))
|
||||||
|
| Dragging::Queues(_) => (),
|
||||||
|
Dragging::Queue(Err(path)) => {
|
||||||
|
self.exec_gui_action(GuiAction::SendToServer(Command::QueueRemove(path)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some(a) = self
|
if let Some(a) = self
|
||||||
.gui
|
.gui
|
||||||
|
@ -16,7 +16,7 @@ use speedy2d::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gui::{Dragging, DrawInfo, GuiAction, GuiElem, GuiElemCfg},
|
gui::{Dragging, DrawInfo, GuiAction, GuiElem, GuiElemCfg},
|
||||||
gui_base::{Button, Panel, ScrollBox, ScrollBoxSizeUnit},
|
gui_base::{Panel, ScrollBox},
|
||||||
gui_text::{self, AdvancedLabel, Label, TextField},
|
gui_text::{self, AdvancedLabel, Label, TextField},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -400,25 +400,33 @@ impl GuiElem for QueueEmptySpaceDragHandler {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
||||||
dragged_add_to_queue(dragged, |q| Command::QueueAdd(vec![], q))
|
dragged_add_to_queue(
|
||||||
|
dragged,
|
||||||
|
(),
|
||||||
|
|_, q| Command::QueueAdd(vec![], q),
|
||||||
|
|_, q| Command::QueueMoveInto(q, vec![]),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generic_queue_draw(
|
fn generic_queue_draw(
|
||||||
info: &mut DrawInfo,
|
info: &mut DrawInfo,
|
||||||
path: &Vec<usize>,
|
path: &Vec<usize>,
|
||||||
|
queue: impl FnOnce() -> Queue,
|
||||||
mouse: &mut bool,
|
mouse: &mut bool,
|
||||||
copy_on_mouse_down: bool,
|
copy_on_mouse_down: bool,
|
||||||
) -> bool {
|
) {
|
||||||
if *mouse && !info.pos.contains(info.mouse_pos) {
|
if *mouse && !info.pos.contains(info.mouse_pos) {
|
||||||
|
// mouse left our element
|
||||||
*mouse = false;
|
*mouse = false;
|
||||||
if !copy_on_mouse_down {
|
info.actions.push(GuiAction::SetDragging(Some((
|
||||||
info.actions
|
Dragging::Queue(if copy_on_mouse_down {
|
||||||
.push(GuiAction::SendToServer(Command::QueueRemove(path.clone())));
|
Ok(queue())
|
||||||
}
|
} else {
|
||||||
true
|
Err(path.clone())
|
||||||
} else {
|
}),
|
||||||
false
|
None,
|
||||||
|
))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,12 +602,13 @@ impl GuiElem for QueueSong {
|
|||||||
info.mouse_pos.y - self.config.pixel_pos.top_left().y,
|
info.mouse_pos.y - self.config.pixel_pos.top_left().y,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if generic_queue_draw(info, &self.path, &mut self.mouse, self.copy_on_mouse_down) {
|
generic_queue_draw(
|
||||||
info.actions.push(GuiAction::SetDragging(Some((
|
info,
|
||||||
Dragging::Queue(QueueContent::Song(self.song.id).into()),
|
&self.path,
|
||||||
None,
|
|| QueueContent::Song(self.song.id).into(),
|
||||||
))));
|
&mut self.mouse,
|
||||||
}
|
self.copy_on_mouse_down,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
fn key_watch(
|
fn key_watch(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -613,15 +622,26 @@ impl GuiElem for QueueSong {
|
|||||||
}
|
}
|
||||||
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
||||||
if !self.always_copy {
|
if !self.always_copy {
|
||||||
let mut p = self.path.clone();
|
|
||||||
let insert_below = self.insert_below;
|
let insert_below = self.insert_below;
|
||||||
dragged_add_to_queue(dragged, move |q| {
|
dragged_add_to_queue(
|
||||||
if let Some(j) = p.pop() {
|
dragged,
|
||||||
Command::QueueInsert(p.clone(), if insert_below { j + 1 } else { j }, q)
|
self.path.clone(),
|
||||||
} else {
|
move |mut p: Vec<usize>, q| {
|
||||||
Command::QueueAdd(p.clone(), q)
|
if let Some(j) = p.pop() {
|
||||||
}
|
Command::QueueInsert(p, if insert_below { j + 1 } else { j }, q)
|
||||||
})
|
} else {
|
||||||
|
Command::QueueAdd(p, q)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
move |mut p, q| {
|
||||||
|
if insert_below {
|
||||||
|
if let Some(l) = p.last_mut() {
|
||||||
|
*l += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command::QueueMove(q, p)
|
||||||
|
},
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
@ -747,12 +767,13 @@ impl GuiElem for QueueFolder {
|
|||||||
info.mouse_pos.y - self.config.pixel_pos.top_left().y,
|
info.mouse_pos.y - self.config.pixel_pos.top_left().y,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if generic_queue_draw(info, &self.path, &mut self.mouse, self.copy_on_mouse_down) {
|
generic_queue_draw(
|
||||||
info.actions.push(GuiAction::SetDragging(Some((
|
info,
|
||||||
Dragging::Queue(QueueContent::Folder(self.queue.clone()).into()),
|
&self.path,
|
||||||
None,
|
|| QueueContent::Folder(self.queue.clone()).into(),
|
||||||
))));
|
&mut self.mouse,
|
||||||
}
|
self.copy_on_mouse_down,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
fn mouse_down(&mut self, button: MouseButton) -> Vec<GuiAction> {
|
fn mouse_down(&mut self, button: MouseButton) -> Vec<GuiAction> {
|
||||||
if button == MouseButton::Left {
|
if button == MouseButton::Left {
|
||||||
@ -797,12 +818,22 @@ impl GuiElem for QueueFolder {
|
|||||||
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
||||||
if !self.always_copy {
|
if !self.always_copy {
|
||||||
if self.insert_into {
|
if self.insert_into {
|
||||||
let p = self.path.clone();
|
dragged_add_to_queue(
|
||||||
dragged_add_to_queue(dragged, move |q| Command::QueueAdd(p.clone(), q))
|
dragged,
|
||||||
|
self.path.clone(),
|
||||||
|
|p, q| Command::QueueAdd(p, q),
|
||||||
|
|p, q| Command::QueueMoveInto(q, p),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
let mut p = self.path.clone();
|
dragged_add_to_queue(
|
||||||
let j = p.pop().unwrap_or(0);
|
dragged,
|
||||||
dragged_add_to_queue(dragged, move |q| Command::QueueInsert(p.clone(), j, q))
|
self.path.clone(),
|
||||||
|
|mut p, q| {
|
||||||
|
let j = p.pop().unwrap_or(0);
|
||||||
|
Command::QueueInsert(p, j, q)
|
||||||
|
},
|
||||||
|
|p, q| Command::QueueMove(q, p),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
@ -863,8 +894,15 @@ impl GuiElem for QueueIndentEnd {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
fn dragged(&mut self, dragged: Dragging) -> Vec<GuiAction> {
|
||||||
let (p, j) = self.path_insert.clone();
|
dragged_add_to_queue(
|
||||||
dragged_add_to_queue(dragged, move |q| Command::QueueInsert(p.clone(), j, q))
|
dragged,
|
||||||
|
self.path_insert.clone(),
|
||||||
|
|(p, j), q| Command::QueueInsert(p, j, q),
|
||||||
|
|(mut p, j), q| {
|
||||||
|
p.push(j);
|
||||||
|
Command::QueueMove(q, p)
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -974,12 +1012,13 @@ impl GuiElem for QueueLoop {
|
|||||||
info.mouse_pos.y - self.config.pixel_pos.top_left().y,
|
info.mouse_pos.y - self.config.pixel_pos.top_left().y,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if generic_queue_draw(info, &self.path, &mut self.mouse, self.copy_on_mouse_down) {
|
generic_queue_draw(
|
||||||
info.actions.push(GuiAction::SetDragging(Some((
|
info,
|
||||||
Dragging::Queue(self.queue.clone()),
|
&self.path,
|
||||||
None,
|
|| self.queue.clone(),
|
||||||
))));
|
&mut self.mouse,
|
||||||
}
|
self.copy_on_mouse_down,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
fn mouse_down(&mut self, button: MouseButton) -> Vec<GuiAction> {
|
fn mouse_down(&mut self, button: MouseButton) -> Vec<GuiAction> {
|
||||||
if button == MouseButton::Left {
|
if button == MouseButton::Left {
|
||||||
@ -1016,22 +1055,29 @@ impl GuiElem for QueueLoop {
|
|||||||
if !self.always_copy {
|
if !self.always_copy {
|
||||||
let mut p = self.path.clone();
|
let mut p = self.path.clone();
|
||||||
p.push(0);
|
p.push(0);
|
||||||
dragged_add_to_queue(dragged, move |q| Command::QueueAdd(p.clone(), q))
|
dragged_add_to_queue(
|
||||||
|
dragged,
|
||||||
|
p,
|
||||||
|
|p, q| Command::QueueAdd(p, q),
|
||||||
|
|p, q| Command::QueueMoveInto(q, p),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dragged_add_to_queue<F: FnOnce(Vec<Queue>) -> Command + 'static>(
|
fn dragged_add_to_queue<T: 'static>(
|
||||||
dragged: Dragging,
|
dragged: Dragging,
|
||||||
f: F,
|
data: T,
|
||||||
|
f_queues: impl FnOnce(T, Vec<Queue>) -> Command + 'static,
|
||||||
|
f_queue_by_path: impl FnOnce(T, Vec<usize>) -> Command + 'static,
|
||||||
) -> Vec<GuiAction> {
|
) -> Vec<GuiAction> {
|
||||||
match dragged {
|
match dragged {
|
||||||
Dragging::Artist(id) => {
|
Dragging::Artist(id) => {
|
||||||
vec![GuiAction::Build(Box::new(move |db| {
|
vec![GuiAction::Build(Box::new(move |db| {
|
||||||
if let Some(q) = add_to_queue_artist_by_id(id, db) {
|
if let Some(q) = add_to_queue_artist_by_id(id, db) {
|
||||||
vec![GuiAction::SendToServer(f(vec![q]))]
|
vec![GuiAction::SendToServer(f_queues(data, vec![q]))]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
@ -1040,7 +1086,7 @@ fn dragged_add_to_queue<F: FnOnce(Vec<Queue>) -> Command + 'static>(
|
|||||||
Dragging::Album(id) => {
|
Dragging::Album(id) => {
|
||||||
vec![GuiAction::Build(Box::new(move |db| {
|
vec![GuiAction::Build(Box::new(move |db| {
|
||||||
if let Some(q) = add_to_queue_album_by_id(id, db) {
|
if let Some(q) = add_to_queue_album_by_id(id, db) {
|
||||||
vec![GuiAction::SendToServer(f(vec![q]))]
|
vec![GuiAction::SendToServer(f_queues(data, vec![q]))]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
@ -1048,12 +1094,13 @@ fn dragged_add_to_queue<F: FnOnce(Vec<Queue>) -> Command + 'static>(
|
|||||||
}
|
}
|
||||||
Dragging::Song(id) => {
|
Dragging::Song(id) => {
|
||||||
let q = QueueContent::Song(id).into();
|
let q = QueueContent::Song(id).into();
|
||||||
vec![GuiAction::SendToServer(f(vec![q]))]
|
vec![GuiAction::SendToServer(f_queues(data, vec![q]))]
|
||||||
}
|
}
|
||||||
Dragging::Queue(q) => {
|
Dragging::Queue(q) => vec![GuiAction::SendToServer(match q {
|
||||||
vec![GuiAction::SendToServer(f(vec![q]))]
|
Ok(q) => f_queues(data, vec![q]),
|
||||||
}
|
Err(p) => f_queue_by_path(data, p),
|
||||||
Dragging::Queues(q) => vec![GuiAction::SendToServer(f(q))],
|
})],
|
||||||
|
Dragging::Queues(q) => vec![GuiAction::SendToServer(f_queues(data, q))],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,6 +559,71 @@ impl Database {
|
|||||||
Command::QueueRemove(index) => {
|
Command::QueueRemove(index) => {
|
||||||
self.queue.remove_by_index(&index, 0);
|
self.queue.remove_by_index(&index, 0);
|
||||||
}
|
}
|
||||||
|
Command::QueueMove(index_from, mut index_to) => 'queue_move: {
|
||||||
|
if index_to.len() == 0 || index_to.starts_with(&index_from) {
|
||||||
|
break 'queue_move;
|
||||||
|
}
|
||||||
|
// if same parent path, perform folder move operation instead
|
||||||
|
if index_from[0..index_from.len() - 1] == index_to[0..index_to.len() - 1] {
|
||||||
|
if let Some(parent) = self
|
||||||
|
.queue
|
||||||
|
.get_item_at_index_mut(&index_from[0..index_from.len() - 1], 0)
|
||||||
|
{
|
||||||
|
if let QueueContent::Folder(folder) = parent.content_mut() {
|
||||||
|
let i1 = index_from[index_from.len() - 1];
|
||||||
|
let mut i2 = index_to[index_to.len() - 1];
|
||||||
|
if i2 > i1 {
|
||||||
|
i2 -= 1;
|
||||||
|
}
|
||||||
|
// this preserves "is currently active queue element" status
|
||||||
|
folder.move_elem(i1, i2);
|
||||||
|
break 'queue_move;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// otherwise, remove then insert
|
||||||
|
let was_current = self.queue.is_current(&index_from);
|
||||||
|
if let Some(elem) = self.queue.remove_by_index(&index_from, 0) {
|
||||||
|
if index_to.len() >= index_from.len()
|
||||||
|
&& index_to.starts_with(&index_from[0..index_from.len() - 1])
|
||||||
|
&& index_to[index_from.len() - 1] > index_from[index_from.len() - 1]
|
||||||
|
{
|
||||||
|
index_to[index_from.len() - 1] -= 1;
|
||||||
|
}
|
||||||
|
if let Some(parent) = self
|
||||||
|
.queue
|
||||||
|
.get_item_at_index_mut(&index_to[0..index_to.len() - 1], 0)
|
||||||
|
{
|
||||||
|
parent.insert(vec![elem], index_to[index_to.len() - 1]);
|
||||||
|
if was_current {
|
||||||
|
self.queue.set_index_inner(&index_to, 0, vec![]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Command::QueueMoveInto(index_from, mut parent_to) => 'queue_move_into: {
|
||||||
|
if parent_to.starts_with(&index_from) {
|
||||||
|
break 'queue_move_into;
|
||||||
|
}
|
||||||
|
// remove then insert
|
||||||
|
let was_current = self.queue.is_current(&index_from);
|
||||||
|
if let Some(elem) = self.queue.remove_by_index(&index_from, 0) {
|
||||||
|
if parent_to.len() >= index_from.len()
|
||||||
|
&& parent_to.starts_with(&index_from[0..index_from.len() - 1])
|
||||||
|
&& parent_to[index_from.len() - 1] > index_from[index_from.len() - 1]
|
||||||
|
{
|
||||||
|
parent_to[index_from.len() - 1] -= 1;
|
||||||
|
}
|
||||||
|
if let Some(parent) = self.queue.get_item_at_index_mut(&parent_to, 0) {
|
||||||
|
if let Some(i) = parent.add_to_end(vec![elem]) {
|
||||||
|
if was_current {
|
||||||
|
parent_to.push(i);
|
||||||
|
self.queue.set_index_inner(&parent_to, 0, vec![]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Command::QueueGoto(index) => Queue::set_index_db(self, &index),
|
Command::QueueGoto(index) => Queue::set_index_db(self, &index),
|
||||||
Command::QueueShuffle(path) => {
|
Command::QueueShuffle(path) => {
|
||||||
if let Some(elem) = self.queue.get_item_at_index_mut(&path, 0) {
|
if let Some(elem) = self.queue.get_item_at_index_mut(&path, 0) {
|
||||||
|
@ -41,6 +41,21 @@ impl Queue {
|
|||||||
QueueContent::Loop(..) => None,
|
QueueContent::Loop(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn is_current(&self, index: &[usize]) -> bool {
|
||||||
|
if index.is_empty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
match self.content() {
|
||||||
|
QueueContent::Song(_) => true,
|
||||||
|
QueueContent::Folder(folder) => {
|
||||||
|
folder.index == index[0]
|
||||||
|
&& folder
|
||||||
|
.get_current_immut()
|
||||||
|
.is_some_and(|c| c.is_current(&index[1..]))
|
||||||
|
}
|
||||||
|
QueueContent::Loop(_, _, inner) => index[0] == 0 && inner.is_current(&index[1..]),
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn insert(&mut self, v: Vec<Self>, index: usize) -> bool {
|
pub fn insert(&mut self, v: Vec<Self>, index: usize) -> bool {
|
||||||
match &mut self.content {
|
match &mut self.content {
|
||||||
QueueContent::Song(_) => false,
|
QueueContent::Song(_) => false,
|
||||||
@ -198,16 +213,11 @@ impl Queue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_index_db(db: &mut Database, index: &Vec<usize>) {
|
pub fn set_index_db(db: &mut Database, index: &[usize]) {
|
||||||
db.queue.reset_index();
|
db.queue.reset_index();
|
||||||
db.queue.set_index_inner(index, 0, vec![]);
|
db.queue.set_index_inner(index, 0, vec![]);
|
||||||
}
|
}
|
||||||
pub fn set_index_inner(
|
pub fn set_index_inner(&mut self, index: &[usize], depth: usize, mut build_index: Vec<usize>) {
|
||||||
&mut self,
|
|
||||||
index: &Vec<usize>,
|
|
||||||
depth: usize,
|
|
||||||
mut build_index: Vec<usize>,
|
|
||||||
) {
|
|
||||||
let i = if let Some(i) = index.get(depth) {
|
let i = if let Some(i) = index.get(depth) {
|
||||||
*i
|
*i
|
||||||
} else {
|
} else {
|
||||||
@ -245,7 +255,7 @@ impl Queue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_item_at_index(&self, index: &Vec<usize>, depth: usize) -> Option<&Self> {
|
pub fn get_item_at_index(&self, index: &[usize], depth: usize) -> Option<&Self> {
|
||||||
if let Some(i) = index.get(depth) {
|
if let Some(i) = index.get(depth) {
|
||||||
match &self.content {
|
match &self.content {
|
||||||
QueueContent::Song(_) => None,
|
QueueContent::Song(_) => None,
|
||||||
@ -262,7 +272,7 @@ impl Queue {
|
|||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_item_at_index_mut(&mut self, index: &Vec<usize>, depth: usize) -> Option<&mut Self> {
|
pub fn get_item_at_index_mut(&mut self, index: &[usize], depth: usize) -> Option<&mut Self> {
|
||||||
if let Some(i) = index.get(depth) {
|
if let Some(i) = index.get(depth) {
|
||||||
match &mut self.content {
|
match &mut self.content {
|
||||||
QueueContent::Song(_) => None,
|
QueueContent::Song(_) => None,
|
||||||
@ -280,7 +290,7 @@ impl Queue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_by_index(&mut self, index: &Vec<usize>, depth: usize) -> Option<Self> {
|
pub fn remove_by_index(&mut self, index: &[usize], depth: usize) -> Option<Self> {
|
||||||
if let Some(i) = index.get(depth) {
|
if let Some(i) = index.get(depth) {
|
||||||
match &mut self.content {
|
match &mut self.content {
|
||||||
QueueContent::Song(_) => None,
|
QueueContent::Song(_) => None,
|
||||||
@ -450,6 +460,46 @@ impl QueueFolder {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn move_elem(&mut self, index_from: usize, index_to: usize) -> bool {
|
||||||
|
fn vec_move<T>(vec: &mut Vec<T>, from: usize, to: usize) -> bool {
|
||||||
|
if from < vec.len() && to < vec.len() {
|
||||||
|
if from == to {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
if from < to {
|
||||||
|
let elem = vec.as_mut_ptr().add(from).read();
|
||||||
|
for i in from..to {
|
||||||
|
vec[i] = vec.as_mut_ptr().add(i + 1).read();
|
||||||
|
}
|
||||||
|
vec[to] = elem;
|
||||||
|
} else {
|
||||||
|
let elem = vec.as_mut_ptr().add(from).read();
|
||||||
|
for i in (to..from).rev() {
|
||||||
|
vec[i + 1] = vec.as_mut_ptr().add(i).read();
|
||||||
|
}
|
||||||
|
vec[to] = elem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if self.index == index_from {
|
||||||
|
self.index = index_to;
|
||||||
|
} else if index_from < self.index && self.index <= index_to {
|
||||||
|
self.index -= 1;
|
||||||
|
} else if index_to <= self.index && self.index < index_from {
|
||||||
|
self.index += 1;
|
||||||
|
}
|
||||||
|
if let Some(order) = &mut self.order {
|
||||||
|
vec_move(order, index_from, index_to)
|
||||||
|
} else {
|
||||||
|
vec_move(&mut self.content, index_from, index_to)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub struct QueueFolderIter<'a> {
|
pub struct QueueFolderIter<'a> {
|
||||||
folder: &'a QueueFolder,
|
folder: &'a QueueFolder,
|
||||||
|
@ -39,6 +39,10 @@ pub enum Command {
|
|||||||
QueueAdd(Vec<usize>, Vec<Queue>),
|
QueueAdd(Vec<usize>, Vec<Queue>),
|
||||||
QueueInsert(Vec<usize>, usize, Vec<Queue>),
|
QueueInsert(Vec<usize>, usize, Vec<Queue>),
|
||||||
QueueRemove(Vec<usize>),
|
QueueRemove(Vec<usize>),
|
||||||
|
/// Move an element from A to B
|
||||||
|
QueueMove(Vec<usize>, Vec<usize>),
|
||||||
|
/// Take an element from A and add it to the end of the folder B
|
||||||
|
QueueMoveInto(Vec<usize>, Vec<usize>),
|
||||||
QueueGoto(Vec<usize>),
|
QueueGoto(Vec<usize>),
|
||||||
// sent by clients when they want to shuffle a folder
|
// sent by clients when they want to shuffle a folder
|
||||||
QueueShuffle(Vec<usize>),
|
QueueShuffle(Vec<usize>),
|
||||||
@ -283,8 +287,10 @@ const BYTE_QUEUE_UPDATE: u8 = 0b10_000_000;
|
|||||||
const BYTE_QUEUE_ADD: u8 = 0b10_000_001;
|
const BYTE_QUEUE_ADD: u8 = 0b10_000_001;
|
||||||
const BYTE_QUEUE_INSERT: u8 = 0b10_000_010;
|
const BYTE_QUEUE_INSERT: u8 = 0b10_000_010;
|
||||||
const BYTE_QUEUE_REMOVE: u8 = 0b10_000_100;
|
const BYTE_QUEUE_REMOVE: u8 = 0b10_000_100;
|
||||||
const BYTE_QUEUE_GOTO: u8 = 0b10_001_000;
|
const BYTE_QUEUE_MOVE: u8 = 0b10_001_000;
|
||||||
const BYTE_QUEUE_ACTION: u8 = 0b10_100;
|
const BYTE_QUEUE_MOVE_INTO: u8 = 0b10_001_001;
|
||||||
|
const BYTE_QUEUE_GOTO: u8 = 0b10_001_010;
|
||||||
|
const BYTE_QUEUE_ACTION: u8 = 0b10_001_100;
|
||||||
const SUBBYTE_ACTION_SHUFFLE: u8 = 0b01_000_001;
|
const SUBBYTE_ACTION_SHUFFLE: u8 = 0b01_000_001;
|
||||||
const SUBBYTE_ACTION_SET_SHUFFLE: u8 = 0b01_000_010;
|
const SUBBYTE_ACTION_SET_SHUFFLE: u8 = 0b01_000_010;
|
||||||
const SUBBYTE_ACTION_UNSHUFFLE: u8 = 0b01_000_100;
|
const SUBBYTE_ACTION_UNSHUFFLE: u8 = 0b01_000_100;
|
||||||
@ -348,6 +354,16 @@ impl ToFromBytes for Command {
|
|||||||
s.write_all(&[BYTE_QUEUE_REMOVE])?;
|
s.write_all(&[BYTE_QUEUE_REMOVE])?;
|
||||||
index.to_bytes(s)?;
|
index.to_bytes(s)?;
|
||||||
}
|
}
|
||||||
|
Self::QueueMove(a, b) => {
|
||||||
|
s.write_all(&[BYTE_QUEUE_MOVE])?;
|
||||||
|
a.to_bytes(s)?;
|
||||||
|
b.to_bytes(s)?;
|
||||||
|
}
|
||||||
|
Self::QueueMoveInto(a, b) => {
|
||||||
|
s.write_all(&[BYTE_QUEUE_MOVE_INTO])?;
|
||||||
|
a.to_bytes(s)?;
|
||||||
|
b.to_bytes(s)?;
|
||||||
|
}
|
||||||
Self::QueueGoto(index) => {
|
Self::QueueGoto(index) => {
|
||||||
s.write_all(&[BYTE_QUEUE_GOTO])?;
|
s.write_all(&[BYTE_QUEUE_GOTO])?;
|
||||||
index.to_bytes(s)?;
|
index.to_bytes(s)?;
|
||||||
@ -529,6 +545,8 @@ impl ToFromBytes for Command {
|
|||||||
BYTE_QUEUE_ADD => Self::QueueAdd(from_bytes!(), from_bytes!()),
|
BYTE_QUEUE_ADD => Self::QueueAdd(from_bytes!(), from_bytes!()),
|
||||||
BYTE_QUEUE_INSERT => Self::QueueInsert(from_bytes!(), from_bytes!(), from_bytes!()),
|
BYTE_QUEUE_INSERT => Self::QueueInsert(from_bytes!(), from_bytes!(), from_bytes!()),
|
||||||
BYTE_QUEUE_REMOVE => Self::QueueRemove(from_bytes!()),
|
BYTE_QUEUE_REMOVE => Self::QueueRemove(from_bytes!()),
|
||||||
|
BYTE_QUEUE_MOVE => Self::QueueMove(from_bytes!(), from_bytes!()),
|
||||||
|
BYTE_QUEUE_MOVE_INTO => Self::QueueMoveInto(from_bytes!(), from_bytes!()),
|
||||||
BYTE_QUEUE_GOTO => Self::QueueGoto(from_bytes!()),
|
BYTE_QUEUE_GOTO => Self::QueueGoto(from_bytes!()),
|
||||||
BYTE_QUEUE_ACTION => match s.read_byte()? {
|
BYTE_QUEUE_ACTION => match s.read_byte()? {
|
||||||
SUBBYTE_ACTION_SHUFFLE => Self::QueueShuffle(from_bytes!()),
|
SUBBYTE_ACTION_SHUFFLE => Self::QueueShuffle(from_bytes!()),
|
||||||
|
@ -87,6 +87,8 @@ pub fn add(
|
|||||||
| Command::QueueAdd(..)
|
| Command::QueueAdd(..)
|
||||||
| Command::QueueInsert(..)
|
| Command::QueueInsert(..)
|
||||||
| Command::QueueRemove(..)
|
| Command::QueueRemove(..)
|
||||||
|
| Command::QueueMove(..)
|
||||||
|
| Command::QueueMoveInto(..)
|
||||||
| Command::QueueGoto(..)
|
| Command::QueueGoto(..)
|
||||||
| Command::QueueShuffle(..)
|
| Command::QueueShuffle(..)
|
||||||
| Command::QueueSetShuffle(..)
|
| Command::QueueSetShuffle(..)
|
||||||
|
@ -426,6 +426,8 @@ async fn sse_handler(
|
|||||||
| Command::QueueAdd(..)
|
| Command::QueueAdd(..)
|
||||||
| Command::QueueInsert(..)
|
| Command::QueueInsert(..)
|
||||||
| Command::QueueRemove(..)
|
| Command::QueueRemove(..)
|
||||||
|
| Command::QueueMove(..)
|
||||||
|
| Command::QueueMoveInto(..)
|
||||||
| Command::QueueGoto(..)
|
| Command::QueueGoto(..)
|
||||||
| Command::QueueShuffle(..)
|
| Command::QueueShuffle(..)
|
||||||
| Command::QueueSetShuffle(..)
|
| Command::QueueSetShuffle(..)
|
||||||
|
Loading…
Reference in New Issue
Block a user