[DEV] update seek and better display

This commit is contained in:
Edouard DUPIN 2017-04-08 23:06:00 +02:00
parent 7cc209a13e
commit 746c8ceac4
17 changed files with 168 additions and 80 deletions

View File

@ -64,11 +64,11 @@ namespace appl {
}
}
// TODO : Remove this: Move if in the windows properties
_context.setSize(vec2(800, 600));
_context.setSize(vec2(400, 300));
// eneble the search of the font in the system font path
_context.getFontDefault().setUseExternal(true);
// select font preference of der with a basic application size
_context.getFontDefault().set("DejaVuSerif;FreeSerif;DejaVuSansMono", 19);
_context.getFontDefault().set("DejaVuSerif;FreeSerif;DejaVuSansMono", 12);
// set application widget:
appl::widget::VideoDisplay::createManagerWidget(_context.getWidgetManager());
appl::widget::ListViewer::createManagerWidget(_context.getWidgetManager());

View File

@ -210,6 +210,7 @@ int appl::MediaDecoder::decode_packet(int *_gotFrame, int _cached) {
m_currentVideoTime = m_currentAudioTime;
m_updateVideoTimeStampAfterSeek = false;
m_seekApply = m_currentVideoTime; // => ready to display
APPL_DEBUG("Update seek time: " << m_seekApply);
}
echrono::Duration packetTime(double(m_frame->pkt_pts) * double(m_videoDecoderContext->time_base.num) / double(m_videoDecoderContext->time_base.den));
APPL_VERBOSE("video_frame " << (_cached?"(cached)":"")
@ -250,7 +251,8 @@ int appl::MediaDecoder::decode_packet(int *_gotFrame, int _cached) {
echrono::Duration packetTime(double(m_frame->pkt_pts) * double(m_audioDecoderContext->time_base.num) / double(m_audioDecoderContext->time_base.den));
if (m_updateVideoTimeStampAfterSeek == true) {
// seek specific usecase ==> drop frame to have fast display
m_currentAudioTime = packetTime;
//TODO : UNDERSTAND why : m_currentAudioTime = packetTime;
APPL_DEBUG("Update audio time with packet time: " << packetTime);
} else {
APPL_VERBOSE("audio_frame " << (_cached?"(cached)":"")
<< " n=" << m_audioFrameCount
@ -386,6 +388,17 @@ void appl::MediaDecoder::init(ememory::SharedPtr<ClientProperty> _property, uint
int appl::MediaDecoder::readFunc(uint8_t* _buf, int _bufSize) {
APPL_INFO("call read ... " << m_remote->m_bufferReadPosition << " size=" << _bufSize);
// check if enought data:
m_remote->startStream();
if (m_remote->m_bufferReadPosition >= m_remote->m_buffer.size()) {
return 0;
}
while(m_remote->sizeReadable() == 0) {
APPL_WARNING(" -------- waiting data --------- ");// << m_remote->sizeReadable());
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (m_stopRequested == true) {
return 0;
}
}
int64_t readableSize = m_remote->sizeReadable();
if (_bufSize > readableSize) {
_bufSize = readableSize;
@ -394,12 +407,12 @@ int appl::MediaDecoder::readFunc(uint8_t* _buf, int _bufSize) {
// No data in the buffer
return 0;
}
// Real Load of the data:
{
std::unique_lock<std::mutex> lock(m_remote->m_mutex);
memcpy(_buf, &m_remote->m_buffer[m_remote->m_bufferReadPosition], _bufSize);
m_remote->m_bufferReadPosition += _bufSize;
}
m_remote->startStream();
m_remote->checkIfWeNeedMoreDataFromNetwork();
return _bufSize;
}
@ -457,11 +470,6 @@ int64_t appl::MediaDecoder::seekFunc(int64_t _offset, int _whence) {
m_remote->m_bufferReadPosition = m_remote->m_buffer.size()-1;
}
if (lastPosition != m_remote->m_bufferReadPosition) {
{
// Force the get of new data ==> this is bad TODO : Update this when possible
std::unique_lock<std::mutex> lock(m_remote->m_mutex);
m_remote->m_callInProgress = false;
}
m_remote->checkIfWeNeedMoreDataFromNetwork();
}
return m_remote->m_bufferReadPosition;
@ -469,7 +477,7 @@ int64_t appl::MediaDecoder::seekFunc(int64_t _offset, int _whence) {
bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_t _positionRequest) {
#ifdef DEBUG
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::this_thread::sleep_for(std::chrono::milliseconds(10));
#endif
{
std::unique_lock<std::mutex> lock(m_mutex);
@ -481,7 +489,7 @@ bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_
}
// TODO : Check buffer size ...
zeus::Raw buffer = _fut.get();
APPL_INFO(" ==> receive DATA : " << _positionRequest << " size=" << buffer.size());
APPL_DEBUG(" ==> receive DATA : " << _positionRequest << " size=" << buffer.size());
// copy data
memcpy(&m_buffer[_positionRequest], buffer.data(), buffer.size());
// Update the buffer data and positionning
@ -508,13 +516,14 @@ bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_
it2->first = _positionRequest;
find = true;
break;
} else {
}/* else {
find = true;
break;
}
}*/
++it;
}
if (find == false) {
APPL_ERROR("insert new element in the list of values");
m_bufferFillSection.insert(it, std::pair<uint32_t,uint32_t>(_positionRequest, _positionRequest + buffer.size()));
}
}
@ -524,19 +533,22 @@ bool appl::StreamBuffering::addDataCallback(zeus::Future<zeus::Raw> _fut, int64_
appl::StreamBuffering::StreamBuffering() {
std::unique_lock<std::mutex> lock(m_mutex);
m_callInProgress = false;
m_stopRequested = false;
m_mediaId = 0;
m_bufferReadPosition = 0;
}
void appl::StreamBuffering::stopStream() {
std::unique_lock<std::mutex> lock(m_mutex);
m_stopRequested = true;
}
void appl::StreamBuffering::startStream() {
std::unique_lock<std::mutex> lock(m_mutex);
m_stopRequested = false;
}
// TODO: Add requested section ...
void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
std::unique_lock<std::mutex> lock(m_mutex);
// check if enought data:
@ -549,26 +561,15 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
}
int32_t preDownloadBufferSlot = BUFFER_SIZE_GET_SLOT*3;
// When file is < 200Mo ==> just download all...
#if 1
if (m_buffer.size() < 300*1024*1024) {
preDownloadBufferSlot = m_buffer.size()+10;
}
APPL_VERBOSE("Request DATA ...");
#endif
APPL_DEBUG("Request DATA ... section number = " << m_bufferFillSection.size());
auto it = m_bufferFillSection.begin();
if (it == m_bufferFillSection.end()) {
// no data in the buffer...
//Get some
// start with loading of 1 Mo
APPL_VERBOSE("Request DATA : " << 0 << " size=" << BUFFER_SIZE_GET_SLOT);
auto futData = m_fileHandle.getPart(0, BUFFER_SIZE_GET_SLOT);
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
return localShared->addDataCallback(_fut, 0);
});
m_callInProgress = true;
return;
}
while (it != m_bufferFillSection.end()) {
APPL_VERBOSE("Check : " << it->first << " -> " << it->second << " read-pos=" << m_bufferReadPosition);
APPL_DEBUG("Check : " << it->first << " -> " << it->second << " read-pos=" << m_bufferReadPosition);
if ( m_bufferReadPosition >= it->first
&& m_bufferReadPosition < it->second) {
find = true;
@ -580,15 +581,22 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
if (it->second - m_bufferReadPosition < preDownloadBufferSlot) {
int32_t sizeRequest = BUFFER_SIZE_GET_SLOT;
if (it->second + sizeRequest >= m_buffer.size()) {
APPL_DEBUG("max area: " << it->second << "+" << sizeRequest << "=" << it->second + sizeRequest << " ->" << m_buffer.size());
sizeRequest = m_buffer.size() - it->second;
APPL_DEBUG(" -> sizeRequested=" << sizeRequest);
}
auto it2 = it;
++it2;
if ( it2 != m_bufferFillSection.end()
&& it->second + sizeRequest >= it2->first) {
APPL_DEBUG("empty area: " << it->second << " ->" << it2->first);
sizeRequest = it2->first - it->second;
APPL_DEBUG(" -> sizeRequested=" << sizeRequest);
}
APPL_VERBOSE("Request DATA : " << it->second << " size=" << sizeRequest);
if (sizeRequest == 0) {
return;
}
APPL_DEBUG("Request DATA: " << it->second << " size=" << sizeRequest);
auto futData = m_fileHandle.getPart(it->second, it->second + sizeRequest);
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
@ -603,7 +611,10 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
if (m_bufferReadPosition + sizeRequest >= it->first) {
sizeRequest = it->first - m_bufferReadPosition;
}
APPL_VERBOSE("Request DATA : " << m_bufferReadPosition << " size=" << sizeRequest);
if (sizeRequest == 0) {
return;
}
APPL_DEBUG("Request DATA : " << m_bufferReadPosition << " size=" << sizeRequest);
auto futData = m_fileHandle.getPart(m_bufferReadPosition, m_bufferReadPosition+sizeRequest);
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
@ -615,11 +626,21 @@ void appl::StreamBuffering::checkIfWeNeedMoreDataFromNetwork() {
}
++it;
}
APPL_VERBOSE("Request DATA : " << m_bufferReadPosition << " size=" << BUFFER_SIZE_GET_SLOT);
auto futData = m_fileHandle.getPart(m_bufferReadPosition, m_bufferReadPosition + BUFFER_SIZE_GET_SLOT);
int32_t sizeRequest = BUFFER_SIZE_GET_SLOT;
if (m_bufferReadPosition + sizeRequest >= m_buffer.size()) {
APPL_DEBUG("max area: " << m_bufferReadPosition << "+" << sizeRequest << "=" << m_bufferReadPosition + sizeRequest << " ->" << m_buffer.size());
sizeRequest = m_buffer.size() - m_bufferReadPosition;
APPL_DEBUG(" -> sizeRequested=" << sizeRequest);
}
if (sizeRequest == 0) {
// nothing to request ...
return;
}
APPL_DEBUG("Request DATA : " << m_bufferReadPosition << " size=" << sizeRequest);
auto futData = m_fileHandle.getPart(m_bufferReadPosition, m_bufferReadPosition + sizeRequest);
auto localShared = ememory::dynamicPointerCast<appl::StreamBuffering>(sharedFromThis());
futData.andThen([=](zeus::Future<zeus::Raw> _fut) mutable {
return localShared->addDataCallback(_fut, 0);
return localShared->addDataCallback(_fut, m_bufferReadPosition);
});
m_callInProgress = true;
if (find == false) {

View File

@ -72,9 +72,11 @@ namespace appl {
bool addDataCallback(zeus::Future<zeus::Raw> _fut, int64_t _positionRequest);
void checkIfWeNeedMoreDataFromNetwork();
uint64_t getSize() {
std::unique_lock<std::mutex> lock(m_mutex);
return m_buffer.size();
}
std::vector<std::pair<uint32_t,uint32_t>> getDownloadPart() {
std::unique_lock<std::mutex> lock(m_mutex);
return m_bufferFillSection;
}
int32_t sizeReadable();
@ -164,9 +166,9 @@ namespace appl {
void flushMessage();
void stop() override;
/* ***********************************************
** Section temporary buffer
***********************************************/
/* ***********************************************
** Section temporary buffer
***********************************************/
ememory::SharedPtr<appl::StreamBuffering> m_remote;
public:
// @brief INTERNAL read callback
@ -184,7 +186,7 @@ namespace appl {
std::vector<std::pair<uint32_t,uint32_t>> vals = m_remote->getDownloadPart();
echrono::Duration totalTime = getDuration();
float size = totalTime.toSeconds()/float(m_remote->getSize());
APPL_ERROR(" duration in sec : " << totalTime << " => " << totalTime.toSeconds());
//APPL_ERROR(" duration in sec : " << totalTime << " => " << totalTime.toSeconds());
for (auto &it : vals) {
out.push_back(std::pair<float,float>(float(it.first)*size, float(it.second)*size));
}

View File

@ -219,12 +219,12 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
std::u32string errorString = U"No element Availlable";
m_text.clear();
// to know the size of one line :
vec3 minSize = m_text.calculateSize(char32_t('A'));
if (m_listElement.size() == 0) {
int32_t paddingSize = 2;
vec2 tmpMax = propertyMaxSize->getPixel();
// to know the size of one line :
vec3 minSize = m_text.calculateSize(char32_t('A'));
/*
if (tmpMax.x() <= 999999) {
@ -276,7 +276,7 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
// Here the real Display get a square in pixel of 2cm x 2cm:
vec2 realPixelSize = gale::Dimension(vec2(3,3), gale::distance::centimeter).getPixel();
// TODO : Understand Why this not work ...
realPixelSize = vec2(150,150);
realPixelSize = vec2(minSize.y()*4,minSize.y()*4+6); // add arbitrary 6 pixel ...
// This will generate the number of element that can be displayed:
int32_t verticalNumber = m_size.y() / realPixelSize.y() + 2; // +1 for the not entire view of element and +1 for the moving element view ...
//verticalNumber = 10;
@ -290,14 +290,19 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
m_listDisplay.push_back(elem);
}
}
int32_t offset = m_originScrooled.y() / realPixelSize.y();
APPL_VERBOSE("origin scrolled : " << m_originScrooled << " nb Pixel/element = " << realPixelSize.y() << " offset=" << offset);
for (size_t iii=0; iii<m_listDisplay.size(); ++iii) {
auto elem = m_listDisplay[iii];
if (elem != nullptr) {
elem->m_idCurentElement = iii;
if (iii < m_listElement.size()) {
elem->m_property = m_listElement[iii];
elem->m_idCurentElement = offset + iii;
if (offset + iii < m_listElement.size()) {
elem->m_property = m_listElement[offset + iii];
} else {
elem->m_property.reset();
}
switch(iii%6) {
//switch(iii%6) {
switch((offset + iii)%6) {
case 0:
elem->m_bgColor = etk::color::red;
break;
@ -324,9 +329,12 @@ void appl::widget::ListViewer::onRegenerateDisplay() {
APPL_ERROR("create nullptr");
}
}
//display only ofsetted element
float realOffset = float(int32_t(m_originScrooled.y() / realPixelSize.y())) * realPixelSize.y();
// Now we request display of the elements:
vec2 elementSize = vec2(m_size.x(), int32_t(realPixelSize.y()));
vec2 startPos = vec2(-m_originScrooled.x(), m_size.y()) - vec2(0, elementSize.y()-m_originScrooled.y());
vec2 startPos = vec2(-m_originScrooled.x(), m_size.y()) - vec2(0, elementSize.y()-(m_originScrooled.y()-realOffset));
for (auto &it : m_listDisplay) {
if (it == nullptr) {
startPos -= vec2(0, elementSize.y());
@ -389,11 +397,13 @@ void appl::ElementDisplayed::generateDisplay(vec2 _startPos, vec2 _size) {
m_text.reset();
m_text.setDefaultColorFg(etk::color::black);
vec3 minSize = m_text.calculateSize(char32_t('A'));
vec2 originText = _startPos + vec2(_size.y()+10, _size.y()-minSize.y() - 10);
float borderOffset = 4;
vec2 originText = _startPos + vec2(_size.y()+borderOffset, _size.y()-minSize.y() - borderOffset);
m_text.setPos(originText);
//APPL_INFO("Regenerate display : " << tmpTextOrigin << " " << m_origin << " " << m_size);
//APPL_VERBOSE("[" << getId() << "] {" << errorString << "} display at pos : " << tmpTextOrigin);
m_text.setTextAlignement(originText.x(), originText.x()+_size.x()-_size.y(), ewol::compositing::alignLeft);
m_text.setTextAlignement(originText.x(), originText.x()+_size.x()-_size.y(), ewol::compositing::alignDisable);
// TODO: m_text.setClipping(originText, vec2(originText.x()+_size.x()-_size.y(), _size.y()));
//m_text.setClipping(drawClippingPos, drawClippingSize);
std::string textToDisplay = "<b>" + m_property->m_title + "</b><br/>";
bool newLine = false;

View File

@ -44,7 +44,7 @@ void appl::widget::Player::init() {
subBind(appl::widget::VideoDisplay, "[" + etk::to_string(getId()) + "]appl-player-display", signalDuration, sharedFromThis(), &appl::widget::Player::onCallbackDuration);
subBind(appl::widget::VideoDisplay, "[" + etk::to_string(getId()) + "]appl-player-display", signalFps, sharedFromThis(), &appl::widget::Player::onCallbackFPS);
subBind(ewol::widget::Slider, "[" + etk::to_string(getId()) + "]appl-player-progress-bar", signalChange, sharedFromThis(), &appl::widget::Player::onCallbackSeekRequest);
subBind(appl::widget::ProgressBar, "[" + etk::to_string(getId()) + "]appl-player-progress-bar", signalChange, sharedFromThis(), &appl::widget::Player::onCallbackSeekRequest);
m_display = ememory::dynamicPointerCast<appl::widget::VideoDisplay>(getSubObjectNamed("[" + etk::to_string(getId()) + "]appl-player-display"));
m_progress = ememory::dynamicPointerCast<appl::widget::ProgressBar>(getSubObjectNamed("[" + etk::to_string(getId()) + "]appl-player-progress-bar"));
@ -76,17 +76,48 @@ void appl::widget::Player::playStream(ememory::SharedPtr<appl::ClientProperty> _
}
static std::string timeToStaticString(const echrono::Duration& _time) {
float sec = _time.toSeconds();
int32_t millisecond = int32_t(sec*1000.0f)%999;
int32_t seconds = int32_t(sec)%60;
int32_t minutes = int32_t(sec/60)%60;
int32_t hours = sec/3600;
std::string out;
if (hours!=0) {
out += etk::to_string(hours) + ":";
}
if (minutes<10) {
out += " " + etk::to_string(minutes) + "'";
} else {
out += etk::to_string(minutes) + "'";
}
if (seconds<10) {
out += " " + etk::to_string(seconds) + "\"";
} else {
out += etk::to_string(seconds) + "\"";
}
if (millisecond<10) {
out += " 00" + etk::to_string(millisecond);
} else if (millisecond<100) {
out += " 0" + etk::to_string(millisecond);
} else {
out += etk::to_string(millisecond);
}
return out;
}
void appl::widget::Player::onCallbackDuration(const echrono::Duration& _time) {
//APPL_ERROR("duration = " << _time);
if (m_progress != nullptr) {
m_progress->propertyValue.set(0);
m_progress->propertyMaximum.set(_time.toSeconds());
}
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]appl-player-label-duration", "value", "<font color='black'>" + timeToStaticString(_time) + "</font>");
}
void appl::widget::Player::onCallbackPosition(const echrono::Duration& _time) {
APPL_ERROR("time = " << _time);
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]appl-player-label-time", "value", "<font color='green'>" + etk::to_string(_time) + "</font>");
//APPL_ERROR("time = " << _time);
propertySetOnWidgetNamed("[" + etk::to_string(getId()) + "]appl-player-label-time", "value", "<font color='black'>" + timeToStaticString(_time) + "</font>");
if (m_progress != nullptr) {
m_progress->propertyValue.set(_time.toSeconds());
}
@ -99,7 +130,9 @@ void appl::widget::Player::onCallbackPosition(const echrono::Duration& _time) {
}
void appl::widget::Player::onCallbackSeekRequest(const float& _value) {
//APPL_ERROR("seek at = " << echrono::Duration(_value));
APPL_ERROR("===========================================================================");
APPL_ERROR("seek at = " << echrono::Duration(_value) << " from value=" << _value);
APPL_ERROR("===========================================================================");
if (m_display != nullptr) {
m_display->seek(echrono::Duration(_value));
}

View File

@ -25,7 +25,6 @@ namespace appl {
esignal::Signal<> signalFinished; //!< the play is finished
esignal::Signal<> signalNext; //!< Next file is requested
esignal::Signal<> signalPrevious; //!< Previous file is requested
protected:
Player();
void init() override;

View File

@ -63,7 +63,7 @@ void appl::widget::ProgressBar::onRegenerateDisplay() {
// draw all availlable section ...
m_draw.setColor(m_textColorLoaded);
for (auto &it: m_listAvaillable) {
APPL_INFO("plop " << it.first << " " << it.second);
//APPL_INFO("plop " << it.first << " " << it.second);
m_draw.setPos(vec3(dotRadius+(it.first/propertyMaximum)*(m_size.x()-2*dotRadius), m_size.y()*0.1, 0));
m_draw.rectangleWidth(vec3((it.second/propertyMaximum)*(m_size.x()-2*dotRadius), m_size.y()*0.8, 0) );
}

View File

@ -258,13 +258,12 @@ void appl::widget::VideoDisplay::periodicEvent(const ewol::event::Time& _event)
APPL_VERBOSE("tick: " << _event);
m_currentTime += _event.getDeltaCallDuration();
}
if (m_decoder == nullptr) {
return;
}
if (m_decoder->m_seekApply >= echrono::Duration(0)) {
m_currentTime = m_decoder->m_seekApply;
//APPL_ERROR("Apply new position : " << m_currentTime);
APPL_ERROR("Apply new position : " << m_currentTime);
m_decoder->m_seekApply = echrono::Duration(-1);
if (m_audioInterface != nullptr) {
m_audioInterface->clearInternalBuffer();
@ -318,6 +317,13 @@ void appl::widget::VideoDisplay::periodicEvent(const ewol::event::Time& _event)
}
// TODO : Chek if this is needed, the display configuration not change too much ...
markToRedraw();
if (m_haveDuration == true) {
if (m_currentTime >= m_decoder->getDuration() + echrono::milliseconds(200)) {
APPL_WARNING("Finish playing");
signalFinish.emit();
stop();
}
}
}
void appl::widget::VideoDisplay::seek(const echrono::Duration& _time) {

View File

@ -26,6 +26,7 @@ namespace appl {
esignal::Signal<int32_t> signalFps;
esignal::Signal<echrono::Duration> signalPosition; //!< signal the current duration of the video duration
esignal::Signal<echrono::Duration> signalDuration; //!< signal the current duration of the video duration
esignal::Signal<> signalFinish; //!< signal the playing is now finished
bool m_haveDuration;
private:
mat4 m_matrixApply;

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg height="100" width="100">
<circle cx="50" cy="50" r="35" stroke="white" stroke-width="5" fill="black" />
<circle cx="20" cy="35" r="10" stroke="white" stroke-width="5" fill="black" />
<circle cx="80" cy="35" r="10" stroke="white" stroke-width="5" fill="black" />
<circle cx="50" cy="85" r="10" stroke="white" stroke-width="5" fill="black" />
</svg>

After

Width:  |  Height:  |  Size: 412 B

View File

@ -2,10 +2,10 @@
<svg width="64" height="64">
<g transform="matrix(1.1999968,0,0,1.3606385,-147.9521,-648.3007)">
<path d="m 170.351,504.021 c -0.343,0.365 -0.922,0.385 -1.288,0.043 L 150.392,486.63 c -0.365,-0.342 -0.966,-0.342 -1.332,0 l -18.204,16.97 c -0.367,0.344 -0.945,0.322 -1.287,-0.045 l -1.865,-2 c -0.342,-0.365 -0.321,-0.945 0.045,-1.287 l 21.313,-19.869 c 0.367,-0.342 0.967,-0.342 1.334,0.002 l 21.777,20.334 c 0.365,0.342 0.386,0.922 0.043,1.289 l -1.865,1.997 z"
style="fill:#333333"/>
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px"/>
<path d="m 149.725,489.777 -15.345,14.305 v 14.83 c 0,0.504 0.414,0.918 0.919,0.918 h 10.085 v -12.857 c 0,-0.504 0.414,-0.918 0.919,-0.918 h 7.347 c 0.506,0 0.918,0.414 0.918,0.918 v 12.857 h 10.119 c 0.505,0 0.918,-0.414 0.918,-0.918 v -14.307 l -15.88,-14.828 z"
style="fill:#333333"/>
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px"/>
<path d="m 165.543,482.311 c 0,-0.506 -0.414,-0.92 -0.919,-0.92 h -5.51 c -0.505,0 -0.918,0.414 -0.918,0.92 v 1.604 l 7.347,6.918 v -8.522 z"
style="fill:#333333"/>
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -2,10 +2,10 @@
<svg width="64" height="64">
<g transform="matrix(1.1999733,0,0,1.1999733,-364.43055,-494.42419)">
<path d="m 352.572,429.142 c 0,0.494 -0.406,0.9 -0.9,0.9 h -43.201 c -0.494,0 -0.9,-0.406 -0.9,-0.9 v -8.099 c 0,-0.496 0.406,-0.9 0.9,-0.9 h 43.201 c 0.494,0 0.9,0.404 0.9,0.9 v 8.099 z"
style="fill:#333333" />
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px" />
<path d="m 352.572,443.542 c 0,0.494 -0.406,0.9 -0.9,0.9 h -43.201 c -0.494,0 -0.9,-0.406 -0.9,-0.9 v -8.1 c 0,-0.496 0.406,-0.9 0.9,-0.9 h 43.201 c 0.494,0 0.9,0.404 0.9,0.9 v 8.1 z"
style="fill:#333333" />
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px" />
<path d="m 352.572,457.942 c 0,0.494 -0.406,0.898 -0.9,0.898 h -43.201 c -0.494,0 -0.9,-0.404 -0.9,-0.898 v -8.102 c 0,-0.494 0.406,-0.898 0.9,-0.898 h 43.201 c 0.494,0 0.9,0.404 0.9,0.898 v 8.102 z"
style="fill:#333333" />
style="fill:#333333;stroke:#FFFFFF;stroke-width:2px" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 842 B

After

Width:  |  Height:  |  Size: 938 B

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="64" height="64">
<path style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
<path style="fill:#000000;fill-rule:evenodd;stroke:#FFFFFF;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="M 16,52 16,62 51,31.991525 16.003261,2.0107803 16,12 39.259882,32.095879 16,52"/>
</svg>

Before

Width:  |  Height:  |  Size: 335 B

After

Width:  |  Height:  |  Size: 335 B

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="64" height="64">
<path style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
<path style="fill:#000000;fill-rule:evenodd;stroke:#FFFFFF;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="M 15,2 52,32 15,62 Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="64" height="64">
<path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
<path style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#FFFFFF;stroke-width:4px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.26828,52 0,10 -35,-30.008475 L 51.265019,2.0107803 51.26828,12 28.008398,32.095879 51.26828,52"/>
</svg>

Before

Width:  |  Height:  |  Size: 356 B

After

Width:  |  Height:  |  Size: 356 B

View File

@ -3,23 +3,32 @@
<sizer mode="hori" fill="true" expand="true,false">
<spacer expand="true,false" fill="true"/>
<spacer expand="true,false" fill="true"/>
<button name="[{ID}]appl-player-bt-previous">
<label>_T{Previous}</label>
<spacer expand="true,false" fill="true"/>
<button name="[{ID}]appl-player-bt-previous" shape="">
<!--<label>_T{Previous}</label>-->
<image src="DATA:Previous.svg" size="8,8mm"/>
</button>
<spacer expand="true,false" fill="true"/>
<button name="[{ID}]appl-player-bt-play" toggle="true">
<label>_T{Play}</label>
<button name="[{ID}]appl-player-bt-play" toggle="true" shape="">
<!--<label>_T{Play}</label>-->
<image src="DATA:Play.svg" size="8,8mm"/>
<label>_T{Pause}</label>
</button>
<spacer expand="true,false" fill="true"/>
<button name="[{ID}]appl-player-bt-next">
<label>_T{Next}</label>
<button name="[{ID}]appl-player-bt-next" shape="">
<!--<label>_T{Next}</label>-->
<image src="DATA:Next.svg" size="8,8mm" />
</button>
<spacer expand="true,false" fill="true"/>
<label name="[{ID}]appl-player-label-time"/>
<spacer expand="true,false" fill="true"/>
<spacer expand="true,false" fill="true"/>
</sizer>
<appl_ProgressBar name="[{ID}]appl-player-progress-bar" expand="true,false" fill="true" step="0.01" min="0"/>
<sizer mode="hori" fill="true" expand="true,false">
<label name="[{ID}]appl-player-label-time"/>
<spacer expand="true,false" fill="true"/>
<label name="[{ID}]appl-player-label-duration"/>
</sizer>
<spacer expand="true" fill="true"/>
<label name="[{ID}]appl-player-label-fps"/>
</sizer>

View File

@ -38,21 +38,21 @@
<player name="ws-name-player" fill="true" expand="true"/>
</wslider>
<sizer mode="hori" fill="true" expand="true,false" lock="true">
<button name="access-fast-home">
<image src="DATA:Home.svg" size='8,8mm' />
<button name="access-fast-home" shape="">
<image src="DATA:Home.svg" size="8,8mm" />
</button>
<button name="access-fast-group">
<image src="DATA:Group.svg" size='8,8mm' />
<button name="access-fast-group" shape="">
<image src="DATA:Group.svg" size="8,8mm" />
</button>
<!--
<button name="access-fast-tv">
<image src="DATA:Tv.svg" size='8,8mm' />
<image src="DATA:Tv.svg" size="8,8mm" />
</button>
<button name="access-fast-page-previous">
<image src="DATA:Previous.svg" size='8,8mm' />
<image src="DATA:Previous.svg" size="8,8mm" />
</button>
<button name="access-fast-page-next">
<image src="DATA:Next.svg" size='8,8mm' />
<image src="DATA:Next.svg" size="8,8mm" />
</button>
-->
</sizer>
@ -79,7 +79,7 @@
</elem>
</menu>
<entry name="search-entry" fill="true,false" expand="true,false"/>
<button name="search-bt">
<button name="search-bt" shape="">
<image src="DATA:Search.svg" size='8,8mm' />
</button>
</sizer>