Serenity Operating System
1/*
2 * Copyright (c) 2021, Cesar Torres <shortanemoia@protonmail.com>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include "PlaylistWidget.h"
8#include "Player.h"
9#include <AK/LexicalPath.h>
10#include <LibGUI/BoxLayout.h>
11#include <LibGUI/HeaderView.h>
12#include <LibGUI/Model.h>
13#include <LibGUI/Window.h>
14
15PlaylistWidget::PlaylistWidget()
16{
17 set_layout<GUI::VerticalBoxLayout>();
18 m_table_view = add<PlaylistTableView>();
19 m_table_view->set_selection_mode(GUI::AbstractView::SelectionMode::SingleSelection);
20 m_table_view->set_selection_behavior(GUI::AbstractView::SelectionBehavior::SelectRows);
21 m_table_view->set_highlight_selected_rows(true);
22 m_table_view->on_doubleclick = [&](Gfx::Point<int> const& point) {
23 auto player = dynamic_cast<Player*>(window()->main_widget());
24 auto index = m_table_view->index_at_event_position(point);
25 if (!index.is_valid())
26 return;
27 player->play_file_path(m_table_view->model()->data(index, static_cast<GUI::ModelRole>(PlaylistModelCustomRole::FilePath)).as_string());
28 };
29}
30
31GUI::Variant PlaylistModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
32{
33 if (role == GUI::ModelRole::TextAlignment)
34 return "CenterLeft";
35 if (role == GUI::ModelRole::Display) {
36 switch (index.column()) {
37 case 0:
38 return m_playlist_items[index.row()].extended_info->track_display_title.value_or(LexicalPath::title(m_playlist_items[index.row()].path));
39 case 1:
40 return format_duration(m_playlist_items[index.row()].extended_info->track_length_in_seconds.value_or(0));
41 case 2:
42 return m_playlist_items[index.row()].extended_info->group_name.value_or("");
43 case 3:
44 return m_playlist_items[index.row()].extended_info->album_title.value_or("");
45 case 4:
46 return m_playlist_items[index.row()].extended_info->album_artist.value_or("");
47 case 5:
48 return format_filesize(m_playlist_items[index.row()].extended_info->file_size_in_bytes.value_or(0));
49 }
50 }
51 if (role == GUI::ModelRole::Sort)
52 return data(index, GUI::ModelRole::Display);
53 if (role == static_cast<GUI::ModelRole>(PlaylistModelCustomRole::FilePath)) // path
54 return m_playlist_items[index.row()].path;
55
56 return {};
57}
58
59DeprecatedString PlaylistModel::format_filesize(u64 size_in_bytes)
60{
61 if (size_in_bytes > GiB)
62 return DeprecatedString::formatted("{:.2f} GiB", (double)size_in_bytes / GiB);
63 else if (size_in_bytes > MiB)
64 return DeprecatedString::formatted("{:.2f} MiB", (double)size_in_bytes / MiB);
65 else if (size_in_bytes > KiB)
66 return DeprecatedString::formatted("{:.2f} KiB", (double)size_in_bytes / KiB);
67 else
68 return DeprecatedString::formatted("{} B", size_in_bytes);
69}
70
71DeprecatedString PlaylistModel::format_duration(u32 duration_in_seconds)
72{
73 return DeprecatedString::formatted("{:02}:{:02}:{:02}", duration_in_seconds / 3600, duration_in_seconds / 60, duration_in_seconds % 60);
74}
75
76DeprecatedString PlaylistModel::column_name(int column) const
77{
78 switch (column) {
79 case 0:
80 return "Title";
81 case 1:
82 return "Duration";
83 case 2:
84 return "Group";
85 case 3:
86 return "Album";
87 case 4:
88 return "Artist";
89 case 5:
90 return "Filesize";
91 }
92 VERIFY_NOT_REACHED();
93}
94
95PlaylistTableView::PlaylistTableView() = default;
96
97void PlaylistTableView::doubleclick_event(GUI::MouseEvent& event)
98{
99 AbstractView::doubleclick_event(event);
100 if (event.button() == GUI::Primary) {
101 if (on_doubleclick)
102 on_doubleclick(event.position());
103 }
104}