#pragma once #include #include #include #include #include #include #include #include #include "imgui.h" #include "imgui_internal.h" #include "tools/cabana/ui/widgets/cameraview.h" #include "tools/cabana/ui/widgets/tabbar.h" #include "tools/cabana/ui/tools/routeinfo.h" #include "tools/replay/logreader.h" #include "tools/cabana/streams/replaystream.h" #include "tools/cabana/ui/icons.h" class Slider { public: Slider() = default; double currentSecond() const { return value() / factor; } void setCurrentSecond(double sec) { setValue(sec * factor); } void setTimeRange(double min, double max) { setRange(min * factor, max * factor); } int value() const { return value_; } void setValue(int v) { value_ = std::clamp(v, minimum_, maximum_); } void setRange(int min, int max) { minimum_ = min; maximum_ = std::max(min, max); setValue(value_); } int minimum() const { return minimum_; } int maximum() const { return maximum_; } bool isSliderDown() const { return slider_down_; } float width() const { return rect_.GetWidth(); } const ImRect &rect() const { return rect_; } bool underMouse() const { return hovered_; } bool mouseLeft() const { return left_; } void draw(double thumbnail_time); static constexpr double factor = 1000.0; Observable<> sliderReleased; private: void handleMousePress(); void paint(double thumbnail_time); ImRect handleRect() const; int pixelPosToRangeValue(float x) const; int minimum_ = 0; int maximum_ = 99; int value_ = 0; bool slider_down_ = false; float click_offset_ = 0; bool hovered_ = false; bool left_ = false; ImRect rect_; }; class StreamCameraView : public CameraWidget { public: StreamCameraView(std::string stream_name, VisionStreamType stream_type); ~StreamCameraView(); void draw(const ImVec2 &size, double thumbnail_time); void parseQLog(std::shared_ptr qlog); private: struct PendingThumbnails { std::future done; std::shared_ptr> thumbnails; }; void collectThumbnails(); const RgbImage *thumbnailAt(double sec, uint64_t *mono_time); void drawAlert(ImDrawList *p, const ImRect &rect, const Timeline::Entry &alert, float font_size); void drawThumbnail(ImDrawList *p, double sec); void drawScrubThumbnail(ImDrawList *p, double sec); void drawTime(ImDrawList *p, const ImRect &rect, double seconds); std::map big_thumbnails_; GlTexture big_thumbnail_texture_; std::vector pending_thumbnails_; }; class VideoWidget { public: VideoWidget(); void draw(); float sizeHintHeight() const; float defaultHeight(float width) const; void setVisible(bool visible); void showThumbnail(double seconds); std::string whatsThis() const; private: void updateSliderThumbnail(); std::string formatTime(double sec, bool include_milliseconds = false); void timeRangeChanged(); void createCameraWidget(); void drawCameraWidget(); void drawPlaybackController(); void skipToEnd(); void toggleTimeDisplay(); void createSpeedDropdown(); void drawSpeedDropdown(float width); void drawSpeedMenuItems(); void loopPlaybackClicked(); void vipcAvailableStreamsUpdated(std::set streams); void showRouteInfo(); std::unique_ptr cam_widget_; std::string speed_text_; int speed_index_ = -1; bool skip_to_end_enabled_ = true; bool msgs_received_ = false; double thumbnail_display_time_ = -1; std::unique_ptr slider_; std::unique_ptr camera_tab_; std::vector> route_info_dlgs_; Connections connections_; };