/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace avmedia { MediaControl::MediaControl( vcl::Window* pParent, MediaControlStyle eControlStyle ) : Control( pParent ), MediaControlBase(), maIdle( "avmedia MediaControl Idle" ), maItem( 0, AVMediaSetMask::ALL ), mbLocked( false ), meControlStyle( eControlStyle ), mfTime(0.0) { mpPlayToolBox = VclPtr::Create(this, WB_3DLOOK) ; mpTimeSlider = VclPtr::Create(this, WB_HORZ | WB_DRAG | WB_3DLOOK) ; mpTimeSlider->SetScrollTypeSet(true); mpMuteToolBox = VclPtr::Create(this, WB_3DLOOK) ; mpVolumeSlider = VclPtr::Create(this, WB_HORZ | WB_DRAG) ; mpVolumeSlider->SetScrollTypeSet(true); mpZoomToolBox = VclPtr::Create(this, WB_3DLOOK) ; mpZoomListBox = VclPtr::Create( mpZoomToolBox.get(), WB_BORDER | WB_DROPDOWN | WB_AUTOHSCROLL | WB_3DLOOK ) ; mpTimeEdit = VclPtr::Create(this, WB_CENTER | WB_READONLY | WB_BORDER | WB_3DLOOK ) ; mpMediaPath = VclPtr::Create(this, WB_VCENTER | WB_READONLY | WB_BORDER | WB_3DLOOK ) ; SetBackground(); SetPaintTransparent( true ); SetParentClipMode( ParentClipMode::NoClip ); InitializeWidgets(); mpPlayToolBox->SetSelectHdl( LINK( this, MediaControl, implSelectHdl ) ); mpPlayToolBox->SetSizePixel( mpPlayToolBox->CalcWindowSizePixel() ); mpPlayToolBox->Show(); maMinSize = mpPlayToolBox->GetSizePixel(); mpTimeSlider->SetSlideHdl( LINK( this, MediaControl, implTimeHdl ) ); mpTimeSlider->SetEndSlideHdl( LINK( this, MediaControl, implTimeEndHdl ) ); mpTimeSlider->SetSizePixel( Size( 128, mpPlayToolBox->GetSizePixel().Height() ) ); mpTimeSlider->Show(); maMinSize.AdjustWidth(mpTimeSlider->GetSizePixel().Width() ); const OUString aTimeText( " 00:00:00/00:00:00 " ); mpTimeEdit->SetSizePixel( Size( mpTimeEdit->GetTextWidth( aTimeText ) + 8, mpPlayToolBox->GetSizePixel().Height() ) ); mpTimeEdit->SetControlBackground( Application::GetSettings().GetStyleSettings().GetWindowColor() ); maMinSize.AdjustWidth(mpTimeEdit->GetSizePixel().Width() ); mpMuteToolBox->SetSelectHdl( LINK( this, MediaControl, implSelectHdl ) ); mpMuteToolBox->SetSizePixel( mpMuteToolBox->CalcWindowSizePixel() ); mpMuteToolBox->Show(); maMinSize.AdjustWidth(mpMuteToolBox->GetSizePixel().Width() ); mpVolumeSlider->SetSlideHdl( LINK( this, MediaControl, implVolumeHdl ) ); mpVolumeSlider->SetSizePixel( Size( 48, mpPlayToolBox->GetSizePixel().Height() ) ); mpVolumeSlider->Show(); maMinSize.AdjustWidth(mpVolumeSlider->GetSizePixel().Width() ); mpZoomListBox->SetSizePixel( Size( mpTimeEdit->GetSizePixel().Width(), 260 ) ); mpZoomListBox->SetSelectHdl( LINK( this, MediaControl, implZoomSelectHdl ) ); mpZoomToolBox->InsertItem( AVMEDIA_TOOLBOXITEM_ZOOM, AvmResId( AVMEDIA_STR_ZOOM ) ); mpZoomToolBox->SetHelpId( AVMEDIA_TOOLBOXITEM_ZOOM, HID_AVMEDIA_ZOOMLISTBOX ); mpZoomToolBox->SetItemWindow( AVMEDIA_TOOLBOXITEM_ZOOM, mpZoomListBox ); mpZoomToolBox->SetSelectHdl( LINK( this, MediaControl, implSelectHdl ) ); mpZoomToolBox->SetSizePixel( mpZoomToolBox->CalcWindowSizePixel() ); mpZoomToolBox->Show(); maMinSize.AdjustWidth(mpZoomToolBox->GetSizePixel().Width() ); const OUString aMediaPath( AvmResId( AVMEDIA_MEDIA_PATH_DEFAULT ) ); mpMediaPath->SetText(aMediaPath); mpMediaPath->SetUpdateMode( false ); mpMediaPath->SetSizePixel( Size( mpMediaPath->GetTextWidth( aMediaPath ) + 400, mpPlayToolBox->GetSizePixel().Height() ) ); // maybe extend the no. 400 to span the screen width mpMediaPath->SetControlBackground( Application::GetSettings().GetStyleSettings().GetWindowColor() ); mpMediaPath->Show(); maMinSize.AdjustWidth(mpMediaPath->GetSizePixel().Width() ); if( meControlStyle == MEDIACONTROLSTYLE_MULTILINE ) { maMinSize.setWidth( 256 ); maMinSize.setHeight( ( maMinSize.Height() << 1 ) + AVMEDIA_CONTROLOFFSET ); mpZoomToolBox->SetBackground(); mpZoomToolBox->SetPaintTransparent( true ); } // we want time field + progress slider to update as the media plays // give this task a lower prio than REPAINT so that UI updates are not starved maIdle.SetPriority( TaskPriority::POST_PAINT ); maIdle.SetInvokeHandler( LINK( this, MediaControl, implTimeoutHdl ) ); } void MediaControl::InitializeWidgets() { if( meControlStyle != MEDIACONTROLSTYLE_SINGLELINE ) { mpPlayToolBox->InsertItem( AVMEDIA_TOOLBOXITEM_OPEN, GetImage(AVMEDIA_TOOLBOXITEM_OPEN), AvmResId( AVMEDIA_STR_OPEN ) ); mpPlayToolBox->SetHelpId( AVMEDIA_TOOLBOXITEM_OPEN, HID_AVMEDIA_TOOLBOXITEM_OPEN ); mpPlayToolBox->InsertItem( AVMEDIA_TOOLBOXITEM_INSERT, GetImage(AVMEDIA_TOOLBOXITEM_INSERT), AvmResId( AVMEDIA_STR_INSERT ) ); mpPlayToolBox->SetHelpId( AVMEDIA_TOOLBOXITEM_INSERT, HID_AVMEDIA_TOOLBOXITEM_INSERT ); mpPlayToolBox->InsertSeparator(); } else { mpZoomListBox->SetBackground(); mpPlayToolBox->SetBackground(); mpPlayToolBox->SetPaintTransparent( true ); mpMuteToolBox->SetBackground(); mpMuteToolBox->SetPaintTransparent( true ); mpMuteToolBox->InsertSeparator(); } avmedia::MediaControlBase::InitializeWidgets(); if( meControlStyle == MEDIACONTROLSTYLE_SINGLELINE ) mpPlayToolBox->InsertSeparator(); } MediaControl::~MediaControl() { disposeOnce(); } void MediaControl::dispose() { mpZoomToolBox->SetItemWindow( AVMEDIA_TOOLBOXITEM_ZOOM, nullptr ); mpZoomListBox.disposeAndClear(); mpTimeEdit.disposeAndClear(); mpMediaPath.disposeAndClear(); mpZoomToolBox.disposeAndClear(); mpVolumeSlider.disposeAndClear(); mpMuteToolBox.disposeAndClear(); mpTimeSlider.disposeAndClear(); mpPlayToolBox.disposeAndClear(); Control::dispose(); } const Size& MediaControl::getMinSizePixel() const { return maMinSize; } void MediaControl::UpdateURLField(MediaItem const & tempItem) { const OUString aURL( AvmResId(AVMEDIA_MEDIA_PATH) + ": " + tempItem.getURL() ) ; mpMediaPath->SetText(aURL); mpMediaPath->SetUpdateMode( false ); mpMediaPath->SetSizePixel( Size( mpMediaPath->GetTextWidth( aURL ) + 8, mpPlayToolBox->GetSizePixel().Height() ) ); mpMediaPath->SetControlBackground( Application::GetSettings().GetStyleSettings().GetWindowColor() ); mpMediaPath->Show(); maMinSize.AdjustWidth(mpMediaPath->GetSizePixel().Width() ); } void MediaControl::Resize() { Point aPos( 0, 0 ); const sal_Int32 nPlayToolBoxWidth = mpPlayToolBox->GetSizePixel().Width(); const sal_Int32 nMuteToolBoxWidth = mpMuteToolBox->GetSizePixel().Width(); const sal_Int32 nVolumeSliderWidth = mpVolumeSlider->GetSizePixel().Width(); const sal_Int32 nZoomToolBoxWidth = mpZoomToolBox->GetSizePixel().Width(); const sal_Int32 nTimeEditWidth = mpTimeEdit->GetSizePixel().Width(); const sal_Int32 nMediaPathWidth = mpMediaPath->GetSizePixel().Width(); const sal_Int32 nTimeSliderHeight = mpTimeSlider->GetSizePixel().Height(); if( meControlStyle == MEDIACONTROLSTYLE_SINGLELINE ) { const sal_Int32 nTimeSliderWidth = GetSizePixel().Width() - ( AVMEDIA_CONTROLOFFSET * 4 ) - nPlayToolBoxWidth - nMuteToolBoxWidth - nVolumeSliderWidth - nTimeEditWidth - nZoomToolBoxWidth - nMediaPathWidth; mpPlayToolBox->SetPosSizePixel( aPos, mpPlayToolBox->GetSizePixel() ); aPos.AdjustX(nPlayToolBoxWidth ); mpTimeSlider->SetPosSizePixel( aPos, Size( nTimeSliderWidth, nTimeSliderHeight ) ); aPos.AdjustX(nTimeSliderWidth + AVMEDIA_CONTROLOFFSET ); mpTimeEdit->SetPosSizePixel( aPos, mpTimeEdit->GetSizePixel() ); aPos.AdjustX(nTimeEditWidth + AVMEDIA_CONTROLOFFSET ); mpMuteToolBox->SetPosSizePixel( aPos, mpMuteToolBox->GetSizePixel() ); aPos.AdjustX(nMuteToolBoxWidth ); mpVolumeSlider->SetPosSizePixel( aPos, mpVolumeSlider->GetSizePixel() ); aPos.AdjustX(nVolumeSliderWidth + AVMEDIA_CONTROLOFFSET ); mpZoomToolBox->SetPosSizePixel( aPos, mpZoomToolBox->GetSizePixel() ); aPos.AdjustX(nZoomToolBoxWidth + AVMEDIA_CONTROLOFFSET ); mpMediaPath->SetPosSizePixel( aPos, mpMediaPath->GetSizePixel() ); } else { const sal_Int32 nTimeSliderWidth = GetSizePixel().Width() - AVMEDIA_CONTROLOFFSET - nTimeEditWidth; mpTimeSlider->SetPosSizePixel( aPos, Size( nTimeSliderWidth, nTimeSliderHeight ) ); aPos.AdjustX(nTimeSliderWidth + AVMEDIA_CONTROLOFFSET ); mpTimeEdit->SetPosSizePixel( aPos, mpTimeEdit->GetSizePixel() ); aPos.setX( 0 ); aPos.AdjustY(nTimeSliderHeight + AVMEDIA_CONTROLOFFSET ); mpPlayToolBox->SetPosSizePixel( aPos, mpPlayToolBox->GetSizePixel() ); aPos.setX( GetSizePixel().Width() - nVolumeSliderWidth - nMuteToolBoxWidth - nZoomToolBoxWidth - AVMEDIA_CONTROLOFFSET ); mpMuteToolBox->SetPosSizePixel( aPos, mpMuteToolBox->GetSizePixel() ); aPos.AdjustX(nMuteToolBoxWidth ); mpVolumeSlider->SetPosSizePixel( aPos, mpVolumeSlider->GetSizePixel() ); aPos.setX( GetSizePixel().Width() - nZoomToolBoxWidth ); mpZoomToolBox->SetPosSizePixel( aPos, mpZoomToolBox->GetSizePixel() ); } } void MediaControl::setState( const MediaItem& rItem ) { double fTime = rItem.getTime(); if( !mbLocked && fTime != mfTime) { mfTime = fTime; maItem.merge( rItem ); if( rItem.getURL().isEmpty() && meControlStyle == MEDIACONTROLSTYLE_SINGLELINE ) mpPlayToolBox->Disable(); UpdateToolBoxes( maItem ); UpdateTimeSlider( maItem ); UpdateVolumeSlider( maItem ); UpdateTimeField( maItem, maItem.getTime() ); UpdateURLField(maItem); } } IMPL_LINK( MediaControl, implTimeHdl, Slider*, p, void ) { mbLocked = true; maIdle.Stop(); UpdateTimeField( maItem, p->GetThumbPos() * maItem.getDuration() / AVMEDIA_TIME_RANGE ); } IMPL_LINK( MediaControl, implTimeEndHdl, Slider*, p, void ) { MediaItem aExecItem; aExecItem.setTime( p->GetThumbPos() * maItem.getDuration() / AVMEDIA_TIME_RANGE ); // keep state (if the media was playing, keep it playing) aExecItem.setState(maItem.getState()); execute( aExecItem ); update(); maIdle.Start(); mbLocked = false; } IMPL_LINK( MediaControl, implVolumeHdl, Slider*, p, void ) { MediaItem aExecItem; aExecItem.setVolumeDB( static_cast< sal_Int16 >( p->GetThumbPos() ) ); execute( aExecItem ); update(); } IMPL_LINK( MediaControl, implSelectHdl, ToolBox*, p, void ) { if( p ) { MediaItem aExecItem; if( p->GetCurItemId() == AVMEDIA_TOOLBOXITEM_OPEN ) { OUString aURL; if (MediaWindow::executeMediaURLDialog(GetFrameWeld(), aURL, nullptr)) { if( !MediaWindow::isMediaURL( aURL, ""/*TODO?*/, true ) ) MediaWindow::executeFormatErrorBox(GetFrameWeld()); else { aExecItem.setURL( aURL, "", ""/*TODO?*/ ); aExecItem.setState( MediaState::Play ); } } } else SelectPlayToolBoxItem( aExecItem, maItem, p->GetCurItemId() ); if (aExecItem.getState() == MediaState::Play) maIdle.Start(); else if (aExecItem.getState() == MediaState::Pause || aExecItem.getState() == MediaState::Stop) maIdle.Stop(); if( aExecItem.getMaskSet() != AVMediaSetMask::NONE ) execute( aExecItem ); } update(); if(p) { p->Invalidate( InvalidateFlags::Update ); } } IMPL_LINK( MediaControl, implZoomSelectHdl, ListBox&, p, void ) { MediaItem aExecItem; css::media::ZoomLevel eLevel; switch( p.GetSelectedEntryPos() ) { case AVMEDIA_ZOOMLEVEL_50: eLevel = css::media::ZoomLevel_ZOOM_1_TO_2; break; case AVMEDIA_ZOOMLEVEL_100: eLevel = css::media::ZoomLevel_ORIGINAL; break; case AVMEDIA_ZOOMLEVEL_200: eLevel = css::media::ZoomLevel_ZOOM_2_TO_1; break; case AVMEDIA_ZOOMLEVEL_FIT: eLevel = css::media::ZoomLevel_FIT_TO_WINDOW_FIXED_ASPECT; break; case AVMEDIA_ZOOMLEVEL_SCALED: eLevel = css::media::ZoomLevel_FIT_TO_WINDOW; break; default: eLevel = css::media::ZoomLevel_NOT_AVAILABLE; break; } aExecItem.setZoom( eLevel ); execute( aExecItem ); update(); } IMPL_LINK_NOARG(MediaControl, implTimeoutHdl, Timer *, void) { update(); maIdle.Start(); } } // namespace avmedia /* vim:set shiftwidth=4 softtabstop=4 expandtab: */