From f3d60dbbadbf7d99c41b8e327daa3518239c822f Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Wed, 2 Jul 2025 23:19:23 +0400 Subject: [PATCH] Add custom sliders --- .../lib/src/mac_cefviewmedia.mm | 3 +- .../lib/src/mac_videoplayer/footerpanel.mm | 32 +++- .../lib/src/mac_videoplayer/footerskin.h | 29 +++- .../lib/src/mac_videoplayer/footerskin.mm | 46 ++++-- .../lib/src/mac_videoplayer/iconpushbutton.h | 2 +- .../lib/src/mac_videoplayer/iconpushbutton.mm | 22 +-- .../lib/src/mac_videoplayer/playerview.h | 2 +- .../lib/src/mac_videoplayer/playerview.mm | 4 +- .../lib/src/mac_videoplayer/slider.h | 11 +- .../lib/src/mac_videoplayer/slider.mm | 147 ++++++++++++++++++ .../lib/src/mac_videoplayer/timelabel.h | 2 +- .../lib/src/mac_videoplayer/timelabel.mm | 14 +- 12 files changed, 262 insertions(+), 52 deletions(-) diff --git a/ChromiumBasedEditors/lib/src/mac_cefviewmedia.mm b/ChromiumBasedEditors/lib/src/mac_cefviewmedia.mm index 1bf05ce8..4138cf80 100644 --- a/ChromiumBasedEditors/lib/src/mac_cefviewmedia.mm +++ b/ChromiumBasedEditors/lib/src/mac_cefviewmedia.mm @@ -49,8 +49,9 @@ void CCefViewMedia::showMediaControl(NSEditorApi::CAscExternalMediaPlayerCommand } m_player_view->SetMedia(data->get_Url()); - // TODO: remove play + // TODO: remove play and mute m_player_view->Play(); + m_player_view->ChangeVolume(0); int nVolume = data->get_Volume(); if (data->get_Mute() || m_pCefView->IsPresentationReporter()) { diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/footerpanel.mm b/ChromiumBasedEditors/lib/src/mac_videoplayer/footerpanel.mm index 12ff385f..2f0f2915 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/footerpanel.mm +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/footerpanel.mm @@ -2,6 +2,7 @@ #import "iconpushbutton.h" #import "timelabel.h" +#import "slider.h" #import "utils.h" // Helper functions for maintaining auto layout @@ -45,6 +46,8 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS NSIconPushButton* m_btn_rewind_back; // text labels NSTimeLabel* m_time_label; + // sliders + NSStyledSlider* m_slider_video; // constraints NSLayoutConstraint* m_time_label_width_constraint; NSLayoutConstraint* m_time_label_height_constraint; @@ -72,7 +75,7 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS const NSSize button_size = NSMakeSize(button_width, button_width); // play button - m_btn_play = [[NSIconPushButton alloc] initWithIconName:@"btn-play" size:button_size skin:&m_skin]; + m_btn_play = [[NSIconPushButton alloc] initWithIconName:@"btn-play" size:button_size style:&m_skin.button]; [self addSubview:m_btn_play]; setLeftConstraintsToView(m_btn_play, self.topAnchor, self.leftAnchor, button_y_offset, button_space_between, button_size); #if !__has_feature(objc_arc) @@ -80,7 +83,7 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS #endif // volume button - m_btn_volume = [[NSIconPushButton alloc] initWithIconName:@"btn-volume-2" size:button_size skin:&m_skin]; + m_btn_volume = [[NSIconPushButton alloc] initWithIconName:@"btn-volume-2" size:button_size style:&m_skin.button]; [self addSubview:m_btn_volume]; setRightConstraintsToView(m_btn_volume, self.topAnchor, self.rightAnchor, button_y_offset, button_space_between, button_size); #if !__has_feature(objc_arc) @@ -88,14 +91,14 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS #endif // time label - m_time_label = [[NSTimeLabel alloc] initWithSkin:&m_skin]; + m_time_label = [[NSTimeLabel alloc] initWithStyle:&m_skin.time_label]; [self addSubview:m_time_label]; NSSize text_bounds = [m_time_label getBoundingBoxSize]; - // manually set all constraints + // manually set all text label constraints m_time_label.translatesAutoresizingMaskIntoConstraints = NO; [m_time_label.centerYAnchor constraintEqualToAnchor:self.centerYAnchor constant:0].active = YES; [m_time_label.rightAnchor constraintEqualToAnchor:m_btn_volume.leftAnchor constant:-button_space_between].active = YES; - // we need to save width and height constraints becuase changing skin may affect text width and height + // we need to save width and height constraints because changing skin may affect text width and height m_time_label_width_constraint = [m_time_label.widthAnchor constraintEqualToConstant:text_bounds.width]; m_time_label_width_constraint.active = YES; m_time_label_height_constraint = [m_time_label.heightAnchor constraintEqualToConstant:text_bounds.height]; @@ -105,7 +108,7 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS #endif // rewind forward button - m_btn_rewind_forward = [[NSIconPushButton alloc] initWithIconName:@"btn-rewind-forward" size:button_size skin:&m_skin]; + m_btn_rewind_forward = [[NSIconPushButton alloc] initWithIconName:@"btn-rewind-forward" size:button_size style:&m_skin.button]; [self addSubview:m_btn_rewind_forward]; setRightConstraintsToView(m_btn_rewind_forward, self.topAnchor, m_time_label.leftAnchor, button_y_offset, button_space_between, button_size); #if !__has_feature(objc_arc) @@ -113,7 +116,7 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS #endif // rewind back button - m_btn_rewind_back = [[NSIconPushButton alloc] initWithIconName:@"btn-rewind-back" size:button_size skin:&m_skin]; + m_btn_rewind_back = [[NSIconPushButton alloc] initWithIconName:@"btn-rewind-back" size:button_size style:&m_skin.button]; [self addSubview:m_btn_rewind_back]; setRightConstraintsToView(m_btn_rewind_back, self.topAnchor, m_btn_rewind_forward.leftAnchor, button_y_offset, button_space_between, button_size); #if !__has_feature(objc_arc) @@ -121,7 +124,18 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS #endif // video slider - // TODO: + m_slider_video = [[NSStyledSlider alloc] initWithStyle:&m_skin.video_slider]; + [self addSubview:m_slider_video]; + // manually set all constraints + m_slider_video.translatesAutoresizingMaskIntoConstraints = NO; + [m_slider_video.centerYAnchor constraintEqualToAnchor:self.centerYAnchor constant:0].active = YES; + [m_slider_video.leftAnchor constraintEqualToAnchor:m_btn_play.rightAnchor constant:button_space_between].active = YES; + [m_slider_video.rightAnchor constraintEqualToAnchor:m_btn_rewind_back.leftAnchor constant:-button_space_between].active = YES; + // TODO: the whole slider area on panel becomes clickable because of this + [m_slider_video.heightAnchor constraintEqualToConstant:frame_rect.size.height].active = YES; +#if !__has_feature(objc_arc) + [m_slider_video release]; +#endif } return self; } @@ -154,6 +168,8 @@ void setRightConstraintsToView(NSView* view, NSLayoutYAxisAnchor* top_anchor, NS NSSize text_bounds = [m_time_label getBoundingBoxSize]; m_time_label_width_constraint.constant = text_bounds.width; m_time_label_height_constraint.constant = text_bounds.height; + // update sliders + [m_slider_video updateStyle]; } @end diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.h b/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.h index 5eeb801d..e4d8f3c2 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.h +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.h @@ -24,6 +24,27 @@ struct CTimeLabelStyle { Color color; }; +struct CSliderStyle { + struct CTrackStyle { + Color color; // color of the track (right of knob) + Color fill_color; // color of the filled portion of the track (left of knob) + int thickness; + int border_radius; + }; + + struct CKnobStyle { + Color color; + Color border_color; + int thickness; + int border_width = 0; + int border_radius = 0; + }; + + CTrackStyle track; + bool is_knob_visible; + CKnobStyle knob; +}; + class CFooterSkin { public: enum class Type { @@ -49,19 +70,21 @@ public: CFooterStyle footer; CButtonStyle button; CTimeLabelStyle time_label; + CSliderStyle video_slider; + CSliderStyle volume_slider; public: // some global constants (skin-independent) + // buttons static constexpr int button_width = 30; static constexpr int button_y_offset = 5; static constexpr int button_space_between = 8; - + // volume controls static constexpr int volume_control_width = 30; static constexpr int volume_control_height = 140; - static constexpr int volume_slider_width = 20; static constexpr int volume_slider_height = 120; - + // general footer panel params static constexpr int border_radius = 5; }; diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.mm b/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.mm index b3a41268..f2b1f7a0 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.mm +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/footerskin.mm @@ -13,15 +13,22 @@ CFooterSkin CFooterSkin::getSkin(Type type) { skin.button.bg_color_pressed = 0xCBCBCB; skin.button.border_radius = 3; - // skin.m_oSliderStyleOpt1.m_sAddColor = "#848484"; - // skin.m_oSliderStyleOpt1.m_sSubColor = "#E2E2E2"; - // skin.m_oSliderStyleOpt1.m_sHandleColor = "#FFFFFF"; - // skin.m_oSliderStyleOpt1.m_sHandleBorderColor = "#444444"; + skin.video_slider.track.color = 0xE2E2E2; + skin.video_slider.track.fill_color = 0x848484; + skin.video_slider.track.thickness = 8; + skin.video_slider.track.border_radius = 4; + skin.video_slider.is_knob_visible = false; - // skin.m_oSliderStyleOpt2.m_sAddColor = "#C0C0C0"; - // skin.m_oSliderStyleOpt2.m_sSubColor = "#E2E2E2"; - // skin.m_oSliderStyleOpt2.m_sHandleColor = "#FFFFFF"; - // skin.m_oSliderStyleOpt2.m_sHandleBorderColor = "#444444"; + skin.volume_slider.track.color = 0xE2E2E2; + skin.volume_slider.track.fill_color = 0xC0C0C0; + skin.volume_slider.track.thickness = 8; + skin.volume_slider.track.border_radius = 4; + skin.volume_slider.is_knob_visible = true; + skin.volume_slider.knob.color = 0xFFFFFF; + skin.volume_slider.knob.border_color = 0x444444; + skin.volume_slider.knob.thickness = 16; + skin.volume_slider.knob.border_width = 2; + skin.volume_slider.knob.border_radius = 8; skin.time_label.font_name = @""; skin.time_label.font_size = 14; @@ -37,15 +44,22 @@ CFooterSkin CFooterSkin::getSkin(Type type) { skin.button.bg_color_pressed = 0x46494B; skin.button.border_radius = 3; - // skin.m_oSliderStyleOpt1.m_sAddColor = "#9B9B9B"; - // skin.m_oSliderStyleOpt1.m_sSubColor = "#545454"; - // skin.m_oSliderStyleOpt1.m_sHandleColor = "#FFFFFF"; - // skin.m_oSliderStyleOpt1.m_sHandleBorderColor = "#222222"; + skin.video_slider.track.color = 0x545454; + skin.video_slider.track.fill_color = 0x9B9B9B; + skin.video_slider.track.thickness = 8; + skin.video_slider.track.border_radius = 4; + skin.video_slider.is_knob_visible = false; - // skin.m_oSliderStyleOpt2.m_sAddColor = "#808080"; - // skin.m_oSliderStyleOpt2.m_sSubColor = "#545454"; - // skin.m_oSliderStyleOpt2.m_sHandleColor = "#FFFFFF"; - // skin.m_oSliderStyleOpt2.m_sHandleBorderColor = "#222222"; + skin.volume_slider.track.color = 0x545454; + skin.volume_slider.track.fill_color = 0x808080; + skin.volume_slider.track.thickness = 8; + skin.volume_slider.track.border_radius = 4; + skin.volume_slider.is_knob_visible = true; + skin.volume_slider.knob.color = 0xFFFFFF; + skin.volume_slider.knob.border_color = 0x222222; + skin.volume_slider.knob.thickness = 16; + skin.volume_slider.knob.border_width = 2; + skin.volume_slider.knob.border_radius = 8; skin.time_label.font_name = @""; skin.time_label.font_size = 14; diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.h b/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.h index ae455f4d..bab0d863 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.h +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.h @@ -6,7 +6,7 @@ #import "footerskin.h" @interface NSIconPushButton : NSButton -- (instancetype)initWithIconName:(NSString*)icon_name size:(NSSize)size skin:(CFooterSkin*)skin; +- (instancetype)initWithIconName:(NSString*)icon_name size:(NSSize)size style:(CButtonStyle*)style; - (void)dealloc; // button appearance diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.mm b/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.mm index 866e6fb3..e4cf8b26 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.mm +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/iconpushbutton.mm @@ -4,7 +4,7 @@ @interface NSIconPushButton () { - CFooterSkin* m_skin; + CButtonStyle* m_style; bool m_hovered; NSString* m_icon_name; } @@ -12,13 +12,13 @@ @implementation NSIconPushButton -- (instancetype)initWithIconName:(NSString*)icon_name size:(NSSize)size skin:(CFooterSkin*)skin { +- (instancetype)initWithIconName:(NSString*)icon_name size:(NSSize)size style:(CButtonStyle*)style { NSRect init_frame_rect = NSMakeRect(0, 0, size.width, size.height); self = [super initWithFrame:init_frame_rect]; if (self) { [self setWantsLayer:YES]; // apply skin - m_skin = skin; + m_style = style; m_icon_name = icon_name; [self updateStyle]; // add mouse tracking for background color or/and icon changing @@ -35,16 +35,16 @@ } - (void)updateStyle { - self.layer.cornerRadius = m_skin->button.border_radius; + self.layer.cornerRadius = m_style->border_radius; self.bordered = NO; - self.layer.backgroundColor = [NSColorFromHex(m_skin->button.bg_color_regular) CGColor]; + self.layer.backgroundColor = [NSColorFromHex(m_style->bg_color_regular) CGColor]; [self setIcon:m_icon_name]; } - (void)setIcon:(NSString*)icon_name { m_icon_name = icon_name; // TODO: are -2x png icons always suitable on mac platforms ??? - NSString* icon_full_name = [NSString stringWithFormat:@"%@%@%@", icon_name, m_skin->button.icon_postfix, @"-2x"]; + NSString* icon_full_name = [NSString stringWithFormat:@"%@%@%@", icon_name, m_style->icon_postfix, @"-2x"]; NSString* icon_path = [[NSBundle mainBundle] pathForResource:icon_full_name ofType:@"png"]; if (icon_path == nil) { NSLog(@"Error: could not load icon %@.png", icon_full_name); @@ -60,25 +60,25 @@ - (void)mouseEntered:(NSEvent*)event { m_hovered = true; - self.layer.backgroundColor = [NSColorFromHex(m_skin->button.bg_color_hovered) CGColor]; + self.layer.backgroundColor = [NSColorFromHex(m_style->bg_color_hovered) CGColor]; } - (void)mouseExited:(NSEvent*)event { m_hovered = false; - self.layer.backgroundColor = [NSColorFromHex(m_skin->button.bg_color_regular) CGColor]; + self.layer.backgroundColor = [NSColorFromHex(m_style->bg_color_regular) CGColor]; } - (void)mouseDown:(NSEvent*)event { - self.layer.backgroundColor = [NSColorFromHex(m_skin->button.bg_color_pressed) CGColor]; + self.layer.backgroundColor = [NSColorFromHex(m_style->bg_color_pressed) CGColor]; NSLog(@"debug: button pressed"); } - (void)mouseUp:(NSEvent*)event { CGColor* bg_color = nil; if (m_hovered) { - bg_color = [NSColorFromHex(m_skin->button.bg_color_hovered) CGColor]; + bg_color = [NSColorFromHex(m_style->bg_color_hovered) CGColor]; } else { - bg_color = [NSColorFromHex(m_skin->button.bg_color_regular) CGColor]; + bg_color = [NSColorFromHex(m_style->bg_color_regular) CGColor]; } self.layer.backgroundColor = bg_color; NSLog(@"debug: button released"); diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.h b/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.h index 235308eb..c4d34a33 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.h +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.h @@ -32,7 +32,7 @@ public: void Play(); void Pause(); void TogglePause(); - void ChangeVolume(int new_value); + void ChangeVolume(CGFloat new_value); void ToggleMute(); bool SetMedia(const std::wstring& media_path); void Stop(); diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.mm b/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.mm index dbcdbd11..3836a863 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.mm +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/playerview.mm @@ -59,8 +59,8 @@ void CPlayerView::TogglePause() { } } -void CPlayerView::ChangeVolume(int new_value) { - // TODO +void CPlayerView::ChangeVolume(CGFloat new_value) { + m_player.volume = new_value; } void CPlayerView::ToggleMute() { diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.h b/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.h index ba4b9a31..7b450875 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.h +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.h @@ -3,8 +3,17 @@ #import -@interface NSVideoSlider : NSSlider +#import "footerskin.h" +@interface NSStyledSlider : NSSlider +- (instancetype)initWithStyle:(CSliderStyle*)style; +- (void)dealloc; + +// slider appearance +- (void)updateStyle; + +// test action function +- (void)sliderValueChanged:(NSSlider*)sender; @end #endif // VIDEOPLAYER_SLIDER_H_ diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.mm b/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.mm index e69de29b..9941fd10 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.mm +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/slider.mm @@ -0,0 +1,147 @@ +#import "slider.h" + +#import "utils.h" + +@interface NSStyledSliderCell : NSSliderCell +{ + CSliderStyle* m_style; + NSImage* m_knob_image; + NSRect m_track_rect; +} +- (instancetype)initWithStyle:(CSliderStyle*)style; +- (void)updateStyle; +@end + +@implementation NSStyledSliderCell + +- (instancetype)initWithStyle:(CSliderStyle*)style { + self = [super init]; + if (self) { + // set skin + m_style = style; + [self updateStyle]; + } + return self; +} + +- (void)drawBarInside:(NSRect)rect flipped:(BOOL)flipped { + // draw the whole track + const CGFloat track_thickness = m_style->track.thickness; + const CGFloat track_border_radius = m_style->track.border_radius; + m_track_rect = NSInsetRect(rect, 0, (rect.size.height - track_thickness) / 2); + NSBezierPath* track_path = [NSBezierPath bezierPathWithRoundedRect:m_track_rect xRadius:track_border_radius yRadius:track_border_radius]; + [NSColorFromHex(m_style->track.color) setFill]; + [track_path fill]; + // draw the filled portion of track (left of knob) + double value = (self.doubleValue - self.minValue) / (self.maxValue - self.minValue); + NSRect filled_rect = m_track_rect; + filled_rect.size.width *= value; + [NSColorFromHex(m_style->track.fill_color) setFill]; + // TODO: when knob is visible, the right part of the filled rect does not have to be rounded + NSBezierPath* filled_path = [NSBezierPath bezierPathWithRoundedRect:filled_rect xRadius:track_border_radius yRadius:track_border_radius]; + [filled_path fill]; +} + +- (NSRect)knobRectFlipped:(BOOL)flipped { + // calculate knob center offset relative to slider current value + // by default we stick knob edge to the edge of the slider track + CGFloat knob_center_max_offset = m_knob_image.size.width / 2; + if (knob_center_max_offset >= m_track_rect.origin.x) { + // if the knob is big enough, then stick it to the control rect edge + knob_center_max_offset -= m_track_rect.origin.x; + } + // this formula essentially means the following: + // - near the edges the knob will have corresponding offset from slider exact value, to be able to fit into control rect + // - at the middle the offset is zero, meaning the knob positioned exactly where slider is + // - the offset changes lineary and flips its sign when knob passes the middle point + CGFloat knob_center_offset = -(knob_center_max_offset * self.doubleValue) / ((self.maxValue - self.minValue) / 2) + knob_center_max_offset; + // get current slider value + double value = (self.doubleValue - self.minValue) / (self.maxValue - self.minValue); + CGFloat slider_pos = m_track_rect.size.width * value + m_track_rect.origin.x; + // create knob rect from the center point + CGFloat knob_center_pos = slider_pos + knob_center_offset; + NSRect knob_rect = NSMakeRect(knob_center_pos - m_knob_image.size.width / 2, NSMidY(m_track_rect) - m_knob_image.size.height / 2, m_knob_image.size.width, m_knob_image.size.height); + return knob_rect; +} + +- (void)drawKnob:(NSRect)knob_rect { + if (m_style->is_knob_visible) { + [m_knob_image drawInRect:knob_rect]; + } +} + +- (void)updateStyle { + // set knob image + if (m_style->is_knob_visible) { + const CGFloat knob_thickness = m_style->knob.thickness; + m_knob_image = [[NSImage imageWithSize:NSMakeSize(knob_thickness, knob_thickness) flipped:NO drawingHandler:^BOOL(NSRect dst_rect) { + // TODO: add border + const CGFloat border_radius = m_style->knob.border_radius; + NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:dst_rect xRadius:border_radius yRadius:border_radius]; + [NSColorFromHex(m_style->knob.color) setFill]; + [path fill]; + return YES; + }] retain]; + } else { + const CGFloat knob_thickness = m_style->track.thickness; + m_knob_image = [[NSImage alloc] initWithSize:NSMakeSize(knob_thickness, knob_thickness)]; + } +} + +- (void)dealloc { + NSLog(@"debug: slider cell deallocated"); +#if !__has_feature(objc_arc) + [m_knob_image release]; + [super dealloc]; +#endif +} + +@end + + +@interface NSStyledSlider () +{ + NSStyledSliderCell* m_cell; +} +@end + +@implementation NSStyledSlider + +- (void)setNeedsDisplayInRect:(NSRect)invalid_rect { + [super setNeedsDisplayInRect:[self bounds]]; +} + +- (instancetype)initWithStyle:(CSliderStyle*)style { + self = [super init]; + if (self) { + [self setWantsLayer:YES]; + // set cell + m_cell = [[NSStyledSliderCell alloc] initWithStyle:style]; + [self setCell:m_cell]; + // set min and max values + self.minValue = 0.0; + self.maxValue = 100.0; + // set action + [self setTarget:self]; + [self setAction:@selector(sliderValueChanged:)]; + } + return self; +} + +- (void)dealloc { + NSLog(@"debug: slider deallocated"); +#if !__has_feature(objc_arc) + [m_cell release]; + [super dealloc]; +#endif +} + +- (void)updateStyle { + [m_cell updateStyle]; +} + +- (void)sliderValueChanged:(NSSlider*)sender { + NSLog(@"debug: slider value changed: %.2f", sender.doubleValue); +} + +@end diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.h b/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.h index 0c191d90..772b4b09 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.h +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.h @@ -6,7 +6,7 @@ #import "footerskin.h" @interface NSTimeLabel : NSTextField -- (instancetype)initWithSkin:(CFooterSkin*)skin; +- (instancetype)initWithStyle:(CTimeLabelStyle*)style; - (void)dealloc; // time label appearance and content diff --git a/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.mm b/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.mm index 236026eb..e8a7dea0 100644 --- a/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.mm +++ b/ChromiumBasedEditors/lib/src/mac_videoplayer/timelabel.mm @@ -4,7 +4,7 @@ @interface NSTimeLabel () { - CFooterSkin* m_skin; + CTimeLabelStyle* m_style; NSDictionary* m_attributes; NSSize m_bounding_box_size; } @@ -12,12 +12,12 @@ @implementation NSTimeLabel -- (instancetype)initWithSkin:(CFooterSkin*)skin { +- (instancetype)initWithStyle:(CTimeLabelStyle*)style { self = [super init]; if (self) { [self setWantsLayer:YES]; // apply skin - m_skin = skin; + m_style = style; [self updateStyle]; // set initial time [self setText:@"00:00:00"]; @@ -40,18 +40,18 @@ - (void)updateStyle { // get font - CGFloat font_size = m_skin->time_label.font_size; + CGFloat font_size = m_style->font_size; NSFont* font = nil; - if (m_skin->time_label.font_name.length == 0) { + if (m_style->font_name.length == 0) { font = [NSFont systemFontOfSize:font_size]; } else { - font = [NSFont fontWithName:m_skin->time_label.font_name size:font_size]; + font = [NSFont fontWithName:m_style->font_name size:font_size]; if (!font) { font = [NSFont systemFontOfSize:font_size]; } } // get color - NSColor* color = NSColorFromHex(m_skin->time_label.color); + NSColor* color = NSColorFromHex(m_style->color); // update attributes m_attributes = @{ NSFontAttributeName: font,