mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-02 13:02:35 +00:00
TracklistInfoView now fully working.
musik::core::tracklist::Standard is rewritten using boost::bimap instead of boost::multi_index. win32cpp updated. Started on MetadataFilterView filtering. Fixed some pragma warnings in PCH files.
This commit is contained in:
parent
d7025b15da
commit
a9b137a9a8
@ -60,7 +60,7 @@ void Query::PlaylistSave::SavePlaylist(int playlistId,utfstring playlistName,mus
|
|||||||
this->playlistName = playlistName;
|
this->playlistName = playlistName;
|
||||||
|
|
||||||
for(int i(0);i<tracklist.Size();++i){
|
for(int i(0);i<tracklist.Size();++i){
|
||||||
musik::core::TrackPtr track=tracklist.Track(i);
|
musik::core::TrackPtr track=tracklist[i];
|
||||||
if(track){
|
if(track){
|
||||||
this->tracks.push_back(track->id);
|
this->tracks.push_back(track->id);
|
||||||
}
|
}
|
||||||
@ -122,3 +122,4 @@ bool Query::PlaylistSave::RunCallbacks(Library::Base *oLibrary){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ void Query::SortTracks::AddTracks(std::vector<int> &tracks){
|
|||||||
void Query::SortTracks::AddTracks(musik::core::tracklist::IRandomAccess &tracks){
|
void Query::SortTracks::AddTracks(musik::core::tracklist::IRandomAccess &tracks){
|
||||||
this->tracksToSort.reserve(this->tracksToSort.size()+tracks.Size());
|
this->tracksToSort.reserve(this->tracksToSort.size()+tracks.Size());
|
||||||
for(int i(0);i<tracks.Size();++i){
|
for(int i(0);i<tracks.Size();++i){
|
||||||
this->tracksToSort.push_back(tracks.Track(i)->id);
|
this->tracksToSort.push_back(tracks[i]->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -196,3 +196,4 @@ void Query::SortTracks::SortByMetaKeys(std::list<std::string> metaKeys){
|
|||||||
this->sortMetaKeys = metaKeys;
|
this->sortMetaKeys = metaKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +37,10 @@
|
|||||||
// Precompiled headers
|
// Precompiled headers
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#pragma warning (disable : 4996 4018 4482)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
@ -64,4 +68,3 @@
|
|||||||
|
|
||||||
#include "vld/vld.h"
|
#include "vld/vld.h"
|
||||||
|
|
||||||
#pragma warning (disable : 4996 4018 4482)
|
|
||||||
|
@ -38,7 +38,9 @@
|
|||||||
|
|
||||||
#include "core/tracklist/IBase.h"
|
#include "core/tracklist/IBase.h"
|
||||||
#include <core/Library/Base.h>
|
#include <core/Library/Base.h>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <sigslot/sigslot.h>
|
||||||
|
|
||||||
namespace musik{ namespace core{
|
namespace musik{ namespace core{
|
||||||
namespace tracklist {
|
namespace tracklist {
|
||||||
@ -46,18 +48,34 @@ namespace musik{ namespace core{
|
|||||||
public:
|
public:
|
||||||
~IRandomAccess(void){};
|
~IRandomAccess(void){};
|
||||||
|
|
||||||
virtual musik::core::TrackPtr operator [](int position) = 0;
|
|
||||||
virtual int Size() = 0;
|
|
||||||
virtual void SetCurrentPosition(int position) = 0;
|
virtual void SetCurrentPosition(int position) = 0;
|
||||||
virtual int CurrentPosition() = 0;
|
virtual int CurrentPosition() = 0;
|
||||||
|
|
||||||
|
virtual int Size() = 0;
|
||||||
|
|
||||||
|
virtual musik::core::TrackPtr operator [](int position) = 0;
|
||||||
|
virtual musik::core::TrackPtr TrackWithMetadata(int position)=0;
|
||||||
|
|
||||||
virtual void SetLibrary(musik::core::LibraryPtr setLibrary) = 0;
|
virtual void SetLibrary(musik::core::LibraryPtr setLibrary) = 0;
|
||||||
virtual musik::core::LibraryPtr Library() = 0;
|
virtual musik::core::LibraryPtr Library() = 0;
|
||||||
|
|
||||||
virtual void CopyTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0;
|
virtual bool CopyTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0;
|
||||||
virtual void AppendTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0;
|
virtual bool AppendTracks(musik::core::tracklist::IRandomAccess &tracklist) = 0;
|
||||||
|
|
||||||
virtual musik::core::TrackPtr Track(int position)=0;
|
virtual void AddRequestedMetakey(const char* metakey) = 0;
|
||||||
|
virtual void RemoveRequestedMetakey(const char* metakey) = 0;
|
||||||
|
|
||||||
|
virtual UINT64 Duration() = 0;
|
||||||
|
virtual UINT64 Filesize() = 0;
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
typedef sigslot::signal3<UINT64,UINT64,UINT64> TracklistInfoEvent;
|
||||||
|
TracklistInfoEvent TracklistInfoUpdated;
|
||||||
|
|
||||||
|
typedef sigslot::signal1<bool> TracksEvent;
|
||||||
|
TracksEvent TracksUpdated;
|
||||||
|
|
||||||
|
typedef sigslot::signal1<std::vector<int>&> TrackMetaEvent;
|
||||||
|
TrackMetaEvent TrackMetaUpdated;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::shared_ptr<IRandomAccess> IRandomAccessPtr;
|
typedef boost::shared_ptr<IRandomAccess> IRandomAccessPtr;
|
||||||
@ -66,3 +84,4 @@ namespace musik{ namespace core{
|
|||||||
} }
|
} }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,9 +40,13 @@
|
|||||||
|
|
||||||
using namespace musik::core::tracklist;
|
using namespace musik::core::tracklist;
|
||||||
|
|
||||||
Standard::Standard(void) : currentPosition(0),hintedRows(10){
|
Standard::Standard(void)
|
||||||
|
:currentPosition(0)
|
||||||
|
,hintedRows(10)
|
||||||
|
,infoDuration(0)
|
||||||
|
,infoFilesize(0)
|
||||||
|
{
|
||||||
this->trackQuery.OnTracksEvent.connect(this,&Standard::OnTracksMetaFromQuery);
|
this->trackQuery.OnTracksEvent.connect(this,&Standard::OnTracksMetaFromQuery);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -50,7 +54,7 @@ Standard::~Standard(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
musik::core::TrackPtr Standard::CurrentTrack(){
|
musik::core::TrackPtr Standard::CurrentTrack(){
|
||||||
return this->Track(this->currentPosition);
|
return (*this)[this->currentPosition];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,25 +70,17 @@ musik::core::TrackPtr Standard::PreviousTrack(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
musik::core::TrackPtr Standard::TrackWithMetadata(int position){
|
||||||
|
this->LoadTrack(position);
|
||||||
|
return (*this)[position];
|
||||||
|
}
|
||||||
|
|
||||||
musik::core::TrackPtr Standard::operator [](int position){
|
musik::core::TrackPtr Standard::operator [](int position){
|
||||||
|
|
||||||
if(position>=0 && position<this->tracks.size())
|
if(position>=0 && position<this->tracks.size())
|
||||||
this->LoadTrack(position);
|
|
||||||
return this->tracks[position];
|
return this->tracks[position];
|
||||||
|
|
||||||
if(position==-1)
|
if(position==-1 && this->tracks.size()>0)
|
||||||
this->LoadTrack(0);
|
|
||||||
return this->tracks.front();
|
|
||||||
|
|
||||||
return musik::core::TrackPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
musik::core::TrackPtr Standard::Track(int position){
|
|
||||||
|
|
||||||
if(position>=0 && position<this->tracks.size())
|
|
||||||
return this->tracks[position];
|
|
||||||
|
|
||||||
if(position==-1)
|
|
||||||
return this->tracks.front();
|
return this->tracks.front();
|
||||||
|
|
||||||
return musik::core::TrackPtr();
|
return musik::core::TrackPtr();
|
||||||
@ -121,6 +117,7 @@ int Standard::CurrentPosition(){
|
|||||||
|
|
||||||
void Standard::ConnectToQuery(musik::core::Query::ListBase &listQuery){
|
void Standard::ConnectToQuery(musik::core::Query::ListBase &listQuery){
|
||||||
listQuery.OnTrackEvent().connect(this,&Standard::OnTracksFromQuery);
|
listQuery.OnTrackEvent().connect(this,&Standard::OnTracksFromQuery);
|
||||||
|
listQuery.OnTrackInfoEvent().connect(this,&Standard::OnTracksInfoFromQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,29 +136,20 @@ void Standard::OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear)
|
|||||||
this->trackCache.clear();
|
this->trackCache.clear();
|
||||||
this->SetCurrentPosition(-1); // undefined
|
this->SetCurrentPosition(-1); // undefined
|
||||||
this->tracks = *newTracks;
|
this->tracks = *newTracks;
|
||||||
this->OnTracks(true);
|
this->TracksUpdated(true);
|
||||||
}else{
|
}else{
|
||||||
this->tracks.insert(this->tracks.end(),newTracks->begin(),newTracks->end());
|
this->tracks.insert(this->tracks.end(),newTracks->begin(),newTracks->end());
|
||||||
this->OnTracks(false);
|
this->TracksUpdated(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Standard::LoadTrack(int position){
|
void Standard::LoadTrack(int position){
|
||||||
|
|
||||||
if(!this->InCache(position)){
|
|
||||||
// Not in cache
|
|
||||||
// Lets load the hinted number of tracks forward
|
|
||||||
int trackCount(0);
|
int trackCount(0);
|
||||||
|
|
||||||
for(int i(position);i<position+this->hintedRows;++i){
|
for(int i(position);i<position+this->hintedRows;++i){
|
||||||
if(!this->InCache(i)){
|
if(this->QueryForTrack(i)){
|
||||||
// Not in cache, load the track and add to Cache
|
|
||||||
musik::core::TrackPtr track = this->Track(i);
|
|
||||||
if(track){
|
|
||||||
this->trackCache.insert(CacheTrack(track,i));
|
|
||||||
++trackCount;
|
++trackCount;
|
||||||
this->trackQuery.RequestTrack(track);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,42 +160,40 @@ void Standard::LoadTrack(int position){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Standard::QueryForTrack(int position){
|
||||||
|
|
||||||
|
TrackCache::left_map::iterator trackIterator = this->trackCache.left.find(position);
|
||||||
|
if(trackIterator==this->trackCache.left.end()){
|
||||||
|
// Not in cache, lets find the track
|
||||||
|
musik::core::TrackPtr track = (*this)[position];
|
||||||
|
if(track){
|
||||||
|
// Track is also a valid track, lets add it to the cache
|
||||||
|
this->trackCache.insert( TrackCache::value_type(position,track) );
|
||||||
|
|
||||||
|
// finally, lets add it to the query
|
||||||
|
this->trackQuery.RequestTrack(track);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Standard::HintNumberOfRows(int rows){
|
void Standard::HintNumberOfRows(int rows){
|
||||||
this->hintedRows = rows;
|
this->hintedRows = rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Standard::InCache(int position){
|
|
||||||
CacheIndexPosition& indexPosition = boost::multi_index::get<tagPosition>(this->trackCache);
|
|
||||||
|
|
||||||
if( indexPosition.find(position) == indexPosition.end() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Standard::InCache(musik::core::TrackPtr track){
|
|
||||||
CacheIndexTrack& indexTrack = boost::multi_index::get<tagTrack>(this->trackCache);
|
|
||||||
|
|
||||||
if( indexTrack.find(track) == indexTrack.end() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Standard::OnTracksMetaFromQuery(musik::core::TrackVector *metaTracks){
|
void Standard::OnTracksMetaFromQuery(musik::core::TrackVector *metaTracks){
|
||||||
std::vector<int> updateTrackPositions;
|
std::vector<int> updateTrackPositions;
|
||||||
CacheIndexTrack& indexTrack = boost::multi_index::get<tagTrack>(this->trackCache);
|
|
||||||
|
|
||||||
for(musik::core::TrackVector::iterator track=metaTracks->begin();track!=metaTracks->end();++track){
|
for(musik::core::TrackVector::iterator track=metaTracks->begin();track!=metaTracks->end();++track){
|
||||||
CacheIndexTrack::iterator cacheTrackIterator = indexTrack.find(*track);
|
TrackCache::right_map::iterator trackPosition = this->trackCache.right.find(*track);
|
||||||
if(cacheTrackIterator!=indexTrack.end()){
|
if(trackPosition!=this->trackCache.right.end()){
|
||||||
updateTrackPositions.push_back(cacheTrackIterator->position);
|
updateTrackPositions.push_back(trackPosition->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->OnTrackMeta(updateTrackPositions);
|
this->TrackMetaUpdated(updateTrackPositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -222,22 +208,26 @@ void Standard::RemoveRequestedMetakey(const char* metakey){
|
|||||||
this->trackQuery.RequestMetakeys(this->requestedMetaKeys);
|
this->trackQuery.RequestMetakeys(this->requestedMetaKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Standard::CopyTracks(musik::core::tracklist::IRandomAccess &tracklist){
|
bool Standard::CopyTracks(musik::core::tracklist::IRandomAccess &tracklist){
|
||||||
if(this!=&tracklist){ // Do not copy to itself
|
if(this!=&tracklist){ // Do not copy to itself
|
||||||
this->trackCache.clear();
|
this->trackCache.clear();
|
||||||
this->SetLibrary(tracklist.Library());
|
this->SetLibrary(tracklist.Library());
|
||||||
this->tracks.clear();
|
this->tracks.clear();
|
||||||
this->tracks.reserve(tracklist.Size());
|
this->tracks.reserve(tracklist.Size());
|
||||||
for(int i(0);i<tracklist.Size();++i){
|
for(int i(0);i<tracklist.Size();++i){
|
||||||
this->tracks.push_back(tracklist.Track(i)->Copy());
|
this->tracks.push_back(tracklist[i]->Copy());
|
||||||
}
|
}
|
||||||
this->SetCurrentPosition(tracklist.CurrentPosition());
|
this->SetCurrentPosition(tracklist.CurrentPosition());
|
||||||
|
|
||||||
this->OnTracks(true);
|
this->TracksUpdated(true);
|
||||||
|
this->infoDuration = tracklist.Duration();
|
||||||
|
this->infoFilesize = tracklist.Filesize();
|
||||||
|
this->TracklistInfoUpdated(this->tracks.size(),this->infoDuration,this->infoFilesize);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Standard::AppendTracks(musik::core::tracklist::IRandomAccess &tracklist){
|
bool Standard::AppendTracks(musik::core::tracklist::IRandomAccess &tracklist){
|
||||||
if(!this->library){
|
if(!this->library){
|
||||||
this->SetLibrary(tracklist.Library());
|
this->SetLibrary(tracklist.Library());
|
||||||
}
|
}
|
||||||
@ -245,10 +235,23 @@ void Standard::AppendTracks(musik::core::tracklist::IRandomAccess &tracklist){
|
|||||||
this->tracks.reserve(this->tracks.size()+tracklist.Size());
|
this->tracks.reserve(this->tracks.size()+tracklist.Size());
|
||||||
|
|
||||||
for(int i(0);i<tracklist.Size();++i){
|
for(int i(0);i<tracklist.Size();++i){
|
||||||
this->tracks.push_back(tracklist.Track(i)->Copy());
|
this->tracks.push_back(tracklist[i]->Copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
this->OnTracks(false);
|
this->TracksUpdated(false);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Standard::OnTracksInfoFromQuery(UINT64 tracks,UINT64 duration,UINT64 filesize){
|
||||||
|
this->infoDuration = duration;
|
||||||
|
this->infoFilesize = filesize;
|
||||||
|
this->TracklistInfoUpdated(tracks,duration,filesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT64 Standard::Duration(){
|
||||||
|
return this->infoDuration;
|
||||||
|
}
|
||||||
|
UINT64 Standard::Filesize(){
|
||||||
|
return this->infoFilesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -43,14 +43,12 @@
|
|||||||
#include <core/Query/TrackMetadata.h>
|
#include <core/Query/TrackMetadata.h>
|
||||||
#include <core/Library/Base.h>
|
#include <core/Library/Base.h>
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <sigslot/sigslot.h>
|
#include <sigslot/sigslot.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/multi_index_container.hpp>
|
#include <boost/bimap.hpp>
|
||||||
#include <boost/multi_index/member.hpp>
|
|
||||||
#include <boost/multi_index/ordered_index.hpp>
|
|
||||||
#include <boost/multi_index/sequenced_index.hpp>
|
|
||||||
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -70,80 +68,56 @@ namespace musik{ namespace core{
|
|||||||
musik::core::TrackPtr NextTrack();
|
musik::core::TrackPtr NextTrack();
|
||||||
musik::core::TrackPtr PreviousTrack();
|
musik::core::TrackPtr PreviousTrack();
|
||||||
|
|
||||||
musik::core::TrackPtr operator [](int position);
|
|
||||||
int Size();
|
|
||||||
void SetCurrentPosition(int position);
|
|
||||||
int CurrentPosition();
|
|
||||||
|
|
||||||
|
virtual void SetCurrentPosition(int position);
|
||||||
|
virtual int CurrentPosition();
|
||||||
|
|
||||||
|
virtual int Size();
|
||||||
|
|
||||||
|
virtual musik::core::TrackPtr operator [](int position);
|
||||||
|
virtual musik::core::TrackPtr TrackWithMetadata(int position);
|
||||||
|
|
||||||
|
virtual void SetLibrary(musik::core::LibraryPtr setLibrary);
|
||||||
|
virtual musik::core::LibraryPtr Library();
|
||||||
|
|
||||||
|
virtual bool CopyTracks(musik::core::tracklist::IRandomAccess &tracklist);
|
||||||
|
virtual bool AppendTracks(musik::core::tracklist::IRandomAccess &tracklist);
|
||||||
|
|
||||||
|
virtual void AddRequestedMetakey(const char* metakey);
|
||||||
|
virtual void RemoveRequestedMetakey(const char* metakey);
|
||||||
|
|
||||||
|
virtual UINT64 Duration();
|
||||||
|
virtual UINT64 Filesize();
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
void ConnectToQuery(musik::core::Query::ListBase &listQuery);
|
void ConnectToQuery(musik::core::Query::ListBase &listQuery);
|
||||||
void SetLibrary(musik::core::LibraryPtr setLibrary);
|
|
||||||
musik::core::LibraryPtr Library();
|
|
||||||
|
|
||||||
void HintNumberOfRows(int rows);
|
void HintNumberOfRows(int rows);
|
||||||
|
|
||||||
void AddRequestedMetakey(const char* metakey);
|
private:
|
||||||
void RemoveRequestedMetakey(const char* metakey);
|
|
||||||
|
|
||||||
void CopyTracks(musik::core::tracklist::IRandomAccess &tracklist);
|
void LoadTrack(int position);
|
||||||
void AppendTracks(musik::core::tracklist::IRandomAccess &tracklist);
|
bool QueryForTrack(int position);
|
||||||
|
void OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear);
|
||||||
typedef sigslot::signal1<bool> TracksEvent;
|
void OnTracksMetaFromQuery(musik::core::TrackVector *metaTracks);
|
||||||
TracksEvent OnTracks;
|
void OnTracksInfoFromQuery(UINT64 tracks,UINT64 duration,UINT64 filesize);
|
||||||
typedef sigslot::signal1<std::vector<int>&> TrackMetaEvent;
|
|
||||||
TrackMetaEvent OnTrackMeta;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
musik::core::TrackPtr Track(int position);
|
|
||||||
|
|
||||||
std::set<std::string> requestedMetaKeys;
|
std::set<std::string> requestedMetaKeys;
|
||||||
|
|
||||||
void LoadTrack(int position);
|
|
||||||
|
|
||||||
int currentPosition;
|
int currentPosition;
|
||||||
|
|
||||||
musik::core::LibraryPtr library;
|
|
||||||
|
|
||||||
musik::core::TrackVector tracks;
|
|
||||||
|
|
||||||
musik::core::Query::TrackMetadata trackQuery;
|
|
||||||
|
|
||||||
void OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear);
|
|
||||||
void OnTracksMetaFromQuery(musik::core::TrackVector *metaTracks);
|
|
||||||
|
|
||||||
int hintedRows;
|
int hintedRows;
|
||||||
|
|
||||||
|
musik::core::LibraryPtr library;
|
||||||
|
musik::core::TrackVector tracks;
|
||||||
|
musik::core::Query::TrackMetadata trackQuery;
|
||||||
|
|
||||||
struct CacheTrack{
|
typedef boost::bimap<int,musik::core::TrackPtr> TrackCache;
|
||||||
CacheTrack(musik::core::TrackPtr track,int position) :
|
|
||||||
track(track),
|
|
||||||
position(position)
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
int position;
|
|
||||||
musik::core::TrackPtr track;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tagPosition{};
|
|
||||||
struct tagTrack{};
|
|
||||||
struct tagPrio{};
|
|
||||||
|
|
||||||
typedef boost::multi_index::ordered_unique<boost::multi_index::tag<tagPosition>,BOOST_MULTI_INDEX_MEMBER(CacheTrack,int,position)> MultiIndexPosition;
|
|
||||||
typedef boost::multi_index::ordered_non_unique<boost::multi_index::tag<tagTrack>,BOOST_MULTI_INDEX_MEMBER(CacheTrack,musik::core::TrackPtr,track)> MultiIndexTrack;
|
|
||||||
typedef boost::multi_index::indexed_by<MultiIndexPosition,MultiIndexTrack> MultiIndexBy;
|
|
||||||
|
|
||||||
typedef boost::multi_index::multi_index_container<CacheTrack,MultiIndexBy> TrackCache;
|
|
||||||
|
|
||||||
/*boost::multi_index::sequenced<tagPrio>,*/
|
|
||||||
|
|
||||||
TrackCache trackCache;
|
TrackCache trackCache;
|
||||||
|
|
||||||
typedef boost::multi_index::index<TrackCache,tagTrack>::type CacheIndexTrack;
|
int infoDuration;
|
||||||
typedef boost::multi_index::index<TrackCache,tagPosition>::type CacheIndexPosition;
|
int infoFilesize;
|
||||||
|
|
||||||
bool InCache(int position);
|
// bool InCache(int position);
|
||||||
bool InCache(musik::core::TrackPtr track);
|
// bool InCache(musik::core::TrackPtr track);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} } // musik::core
|
} } // musik::core
|
||||||
|
@ -112,9 +112,18 @@ void MetadataFilterController::OnViewCreated(Window* window)
|
|||||||
|
|
||||||
this->listView.Resized.connect(
|
this->listView.Resized.connect(
|
||||||
this, &MetadataFilterController::OnResized);
|
this, &MetadataFilterController::OnResized);
|
||||||
|
|
||||||
|
this->listView.Char.connect(this,&MetadataFilterController::OnChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetadataFilterController::OnResized(Window* window, Size size)
|
void MetadataFilterController::OnResized(Window* window, Size size)
|
||||||
{
|
{
|
||||||
this->listView.SetColumnWidth(this->mainColumn, this->listView.ClientSize().width);
|
this->listView.SetColumnWidth(this->mainColumn, this->listView.ClientSize().width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetadataFilterController::OnChar(Window* window,VirtualKeyCode keyCode, KeyEventFlags keyFlags){
|
||||||
|
if(keyCode){
|
||||||
|
win32cpp::RedrawLock drawLock(window);
|
||||||
|
((MetadataFilterModel*)this->model.get())->OnChar((wchar_t)keyCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -55,23 +55,29 @@ class BrowseController;
|
|||||||
|
|
||||||
class MetadataFilterController : public EventHandler
|
class MetadataFilterController : public EventHandler
|
||||||
{
|
{
|
||||||
private: typedef ListView::ColumnRef ColumnRef;
|
private:
|
||||||
private: typedef ListView::ModelRef ModelRef;
|
typedef ListView::ColumnRef ColumnRef;
|
||||||
|
typedef ListView::ModelRef ModelRef;
|
||||||
|
|
||||||
public: /*ctor*/ MetadataFilterController(ListView& listView, const uistring& metdataKey,BrowseController *browseController);
|
public:
|
||||||
|
/*ctor*/ MetadataFilterController(ListView& listView, const uistring& metdataKey,BrowseController *browseController);
|
||||||
|
|
||||||
protected: void OnViewCreated(Window* window);
|
|
||||||
protected: void OnResized(Window* window, Size size);
|
|
||||||
protected: void OnSelectionChanged(ListView* listView);
|
|
||||||
protected:
|
protected:
|
||||||
|
void OnViewCreated(Window* window);
|
||||||
|
void OnResized(Window* window, Size size);
|
||||||
|
void OnSelectionChanged(ListView* listView);
|
||||||
|
void OnChar(Window* window,VirtualKeyCode keyCode, KeyEventFlags keyFlags);
|
||||||
|
|
||||||
|
uistring currentFilter;
|
||||||
|
|
||||||
friend class MetadataFilterModel;
|
friend class MetadataFilterModel;
|
||||||
BrowseController *parent;
|
BrowseController *parent;
|
||||||
uistring metadataKey;
|
uistring metadataKey;
|
||||||
std::string metadataKeyA;
|
std::string metadataKeyA;
|
||||||
|
|
||||||
protected: ListView& listView;
|
ListView& listView;
|
||||||
protected: ModelRef model;
|
ModelRef model;
|
||||||
protected: ColumnRef mainColumn;
|
ColumnRef mainColumn;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
#include <cube/MetadataFilterController.hpp>
|
#include <cube/MetadataFilterController.hpp>
|
||||||
#include <cube/BrowseController.hpp>
|
#include <cube/BrowseController.hpp>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
using namespace musik::cube;
|
using namespace musik::cube;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -67,8 +69,8 @@ uistring MetadataFilterModel::CellValueToString(int rowIndex, ListView::Colum
|
|||||||
return (format(_T("All (%1% %2%)")) % this->metadata.size() % this->controller->metadataKey).str();
|
return (format(_T("All (%1% %2%)")) % this->metadata.size() % this->controller->metadataKey).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rowIndex<=this->metadata.size()){
|
if(rowIndex<=this->metadataFiltered.size()){
|
||||||
return win32cpp::Escape(this->metadata[rowIndex-1]->value);
|
return win32cpp::Escape(this->metadataFiltered[rowIndex-1]->value);
|
||||||
}else{
|
}else{
|
||||||
return uistring();
|
return uistring();
|
||||||
}
|
}
|
||||||
@ -78,9 +80,28 @@ void MetadataFilterModel::OnMetadata(musik::core::MetadataValueVector* me
|
|||||||
if(clear){
|
if(clear){
|
||||||
this->SetRowCount(0);
|
this->SetRowCount(0);
|
||||||
this->metadata = *metadata;
|
this->metadata = *metadata;
|
||||||
|
this->metadataFiltered = *metadata;
|
||||||
|
this->filter.clear();
|
||||||
}else{
|
}else{
|
||||||
this->metadata.insert(this->metadata.end(),metadata->begin(),metadata->end());
|
this->metadata.insert(this->metadata.end(),metadata->begin(),metadata->end());
|
||||||
|
this->metadataFiltered.insert(this->metadataFiltered.end(),metadata->begin(),metadata->end());
|
||||||
}
|
}
|
||||||
this->SetRowCount(this->metadata.size()+1);
|
this->SetRowCount(this->metadataFiltered.size()+1);
|
||||||
this->InvalidateData(0); // Invalidate the "All" count
|
this->InvalidateData(0); // Invalidate the "All" count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetadataFilterModel::OnChar(wchar_t key){
|
||||||
|
/* if(key){
|
||||||
|
this->filter += key;
|
||||||
|
|
||||||
|
// Lets filter
|
||||||
|
this->metadataFiltered.clear();
|
||||||
|
for(musik::core::MetadataValueVector::iterator meta=this->metadata.begin();meta!=this->metadata.end();++meta){
|
||||||
|
if(boost::ifind_first( (*meta)->value, this->filter) ){
|
||||||
|
this->metadataFiltered.push_back(*meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->SetRowCount(0);
|
||||||
|
this->SetRowCount(this->metadataFiltered.size()+1);*/
|
||||||
|
}
|
||||||
|
@ -55,12 +55,22 @@ class MetadataFilterController;
|
|||||||
|
|
||||||
class MetadataFilterModel: public ListView::Model, public EventHandler
|
class MetadataFilterModel: public ListView::Model, public EventHandler
|
||||||
{
|
{
|
||||||
public: /*ctor*/ MetadataFilterModel(MetadataFilterController *controller);
|
public:
|
||||||
public: virtual uistring CellValueToString(int rowIndex, ListView::ColumnRef column);
|
/*ctor*/ MetadataFilterModel(MetadataFilterController *controller);
|
||||||
protected: void OnMetadata(musik::core::MetadataValueVector* metadata,bool clear);
|
virtual uistring CellValueToString(int rowIndex, ListView::ColumnRef column);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnMetadata(musik::core::MetadataValueVector* metadata,bool clear);
|
||||||
|
MetadataFilterController *controller;
|
||||||
|
|
||||||
|
public:
|
||||||
|
musik::core::MetadataValueVector metadata;
|
||||||
|
musik::core::MetadataValueVector metadataFiltered;
|
||||||
|
|
||||||
|
void OnChar(wchar_t key);
|
||||||
|
|
||||||
|
uistring filter;
|
||||||
|
|
||||||
protected: MetadataFilterController *controller;
|
|
||||||
public: musik::core::MetadataValueVector metadata;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -58,8 +58,11 @@ using namespace musik::cube;
|
|||||||
? this->OnViewCreated(&view)
|
? this->OnViewCreated(&view)
|
||||||
: this->view.Created.connect(this, &TracklistController::OnViewCreated);
|
: this->view.Created.connect(this, &TracklistController::OnViewCreated);
|
||||||
|
|
||||||
if(connectedQuery){
|
|
||||||
connectedQuery->OnTrackInfoEvent().connect(this,&TracklistController::OnTracklistInfo);
|
// Connect the tracklists TracklistInfoUpdated
|
||||||
|
TracklistModel* model = (TracklistModel*)this->model.get();
|
||||||
|
if(model){
|
||||||
|
model->tracklist->TracklistInfoUpdated.connect(this,&TracklistController::OnTracklistInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -64,8 +64,8 @@ using namespace musik::cube;
|
|||||||
|
|
||||||
this->SetRowCount(0);
|
this->SetRowCount(0);
|
||||||
|
|
||||||
this->tracklist->OnTracks.connect(this,&TracklistModel::OnTracks);
|
this->tracklist->TracksUpdated.connect(this,&TracklistModel::OnTracks);
|
||||||
this->tracklist->OnTrackMeta.connect(this,&TracklistModel::OnTrackMeta);
|
this->tracklist->TrackMetaUpdated.connect(this,&TracklistModel::OnTrackMeta);
|
||||||
this->tracklist->SetLibrary(musik::core::LibraryFactory::GetCurrentLibrary());
|
this->tracklist->SetLibrary(musik::core::LibraryFactory::GetCurrentLibrary());
|
||||||
|
|
||||||
if(connectedQuery){
|
if(connectedQuery){
|
||||||
@ -81,7 +81,7 @@ uistring TracklistModel::CellValueToString(int rowIndex, ColumnRef co
|
|||||||
|
|
||||||
typedef boost::basic_format<uichar> format;
|
typedef boost::basic_format<uichar> format;
|
||||||
// return (format(_T("%1% %2%")) % column->Name() % (rowIndex + 1)).str();
|
// return (format(_T("%1% %2%")) % column->Name() % (rowIndex + 1)).str();
|
||||||
musik::core::TrackPtr track = (*this->tracklist)[rowIndex];
|
musik::core::TrackPtr track = this->tracklist->TrackWithMetadata(rowIndex);
|
||||||
if(!track){
|
if(!track){
|
||||||
return _T("");
|
return _T("");
|
||||||
}else{
|
}else{
|
||||||
|
@ -38,9 +38,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
//extern "C" void tss_cleanup_implemented(void){}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// dependencies
|
// dependencies
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
#pragma warning (disable : 4996 4018 4482)
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
|
@ -232,13 +232,6 @@ WindowType* Container::RemoveChild(WindowType* window)
|
|||||||
allChildren.erase(
|
allChildren.erase(
|
||||||
std::find(allChildren.begin(), allChildren.end(), window));
|
std::find(allChildren.begin(), allChildren.end(), window));
|
||||||
|
|
||||||
// set the MainWindow as the new parent, but do not add it as
|
|
||||||
// a child. we do this so the child control doesn't get into
|
|
||||||
// a bad state, but does not get automatically destroyed by the
|
|
||||||
// main window. the once a child has been removed from a Container
|
|
||||||
// it is the user's responsibility to clean it up.
|
|
||||||
Window::SetParent(window, Application::Instance().MainWindow());
|
|
||||||
|
|
||||||
this->OnChildRemoved(window);
|
this->OnChildRemoved(window);
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
|
197
src/win32cpp/ProgressBar.cpp
Normal file
197
src/win32cpp/ProgressBar.cpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// License Agreement:
|
||||||
|
//
|
||||||
|
// The following are Copyright © 2007, Casey Langen
|
||||||
|
//
|
||||||
|
// Sources and Binaries of: win32cpp
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// * Neither the name of the author nor the names of other contributors may
|
||||||
|
// be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <pch.hpp>
|
||||||
|
#include <win32cpp/Win32Config.hpp>
|
||||||
|
#include <win32cpp/ProgressBar.hpp>
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
using namespace win32cpp;
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Constructor.
|
||||||
|
///
|
||||||
|
///\param width
|
||||||
|
///The width of the edit box
|
||||||
|
///\param height
|
||||||
|
///The height of the edit box
|
||||||
|
/*ctor*/ ProgressBar::ProgressBar(int width, int height)
|
||||||
|
: base()
|
||||||
|
, width(width)
|
||||||
|
, height(height)
|
||||||
|
//, caption(caption)
|
||||||
|
{
|
||||||
|
this->caption = _T("Progress Bar");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*dtor*/ ProgressBar::~ProgressBar()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND ProgressBar::Create(Window* parent)
|
||||||
|
{
|
||||||
|
HINSTANCE hInstance = Application::Instance();
|
||||||
|
|
||||||
|
// create the window
|
||||||
|
DWORD style = WS_CHILD | WS_VISIBLE;
|
||||||
|
DWORD styleEx = this->styleEx;
|
||||||
|
//
|
||||||
|
HWND hwnd = CreateWindowEx(
|
||||||
|
0, // ExStyle
|
||||||
|
PROGRESS_CLASS, // Class name
|
||||||
|
this->caption.c_str(), // Window name
|
||||||
|
style, // Style
|
||||||
|
0, // X
|
||||||
|
0, // Y
|
||||||
|
this->width, // Width
|
||||||
|
this->height, // Height
|
||||||
|
parent->Handle(), // Parent
|
||||||
|
NULL, // Menu
|
||||||
|
hInstance, // Instance
|
||||||
|
NULL); // lParam
|
||||||
|
|
||||||
|
DWORD error = GetLastError();
|
||||||
|
if (hwnd)
|
||||||
|
{
|
||||||
|
::SetWindowText(hwnd, this->caption.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return hwnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT ProgressBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_COMMAND:
|
||||||
|
{
|
||||||
|
WORD notifyHeader = HIWORD(wParam);
|
||||||
|
switch (notifyHeader)
|
||||||
|
{
|
||||||
|
/*case EN_CHANGE:
|
||||||
|
this->OnChanged();
|
||||||
|
return 0; // 0 = processed*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->DefaultWindowProc(message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Sets the progress bar to have a smooth bar
|
||||||
|
void ProgressBar::SetMarqueeStyle()
|
||||||
|
{
|
||||||
|
SetWindowLongPtr(this->Handle(), GWL_STYLE, GetWindowLongPtr(this->Handle(), GWL_STYLE) | PBS_MARQUEE);
|
||||||
|
SetWindowPos(this->Handle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Sets the progress bar to have a smooth bar
|
||||||
|
void ProgressBar::SetSmoothStyle()
|
||||||
|
{
|
||||||
|
SetWindowLongPtr(this->Handle(), GWL_STYLE, GetWindowLongPtr(this->Handle(), GWL_STYLE) | PBS_SMOOTH);
|
||||||
|
SetWindowPos(this->Handle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Sets the progress bar to have a smooth bar
|
||||||
|
void ProgressBar::SetVerticalStyle()
|
||||||
|
{
|
||||||
|
SetWindowLongPtr(this->Handle(), GWL_STYLE, GetWindowLongPtr(this->Handle(), GWL_STYLE) | PBS_VERTICAL);
|
||||||
|
SetWindowPos(this->Handle(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Sets the progress bar to have a marquee style (Windows XP or above)
|
||||||
|
///\param set
|
||||||
|
///Boolean to say whether to marquee or not
|
||||||
|
///\param delay
|
||||||
|
///Time in milliseconds between animation updates
|
||||||
|
void ProgressBar::StartMarquee(bool set, unsigned int delay)
|
||||||
|
{
|
||||||
|
this->SendMessage(PBM_SETMARQUEE, (WPARAM)set, (LPARAM)delay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Sets the min and max values of the progress bar
|
||||||
|
///\param min
|
||||||
|
///The minimum value (unsigned)
|
||||||
|
///\param max
|
||||||
|
///The maximum value (unsigned)
|
||||||
|
DWORD ProgressBar::SetRange(unsigned int min, unsigned int max)
|
||||||
|
{
|
||||||
|
DWORD prevrange = this->SendMessage(PBM_SETRANGE, 0, MAKELPARAM(min,max));
|
||||||
|
return prevrange;
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Sets the current position of the progress bar
|
||||||
|
///\param pos
|
||||||
|
///The new position of the progress bar
|
||||||
|
void ProgressBar::SetPos(int pos)
|
||||||
|
{
|
||||||
|
this->SendMessage(PBM_SETPOS, pos, 0 /*must be 0. Not used*/);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Sets the current position of the progress bar
|
||||||
|
///\param pos
|
||||||
|
///The new step increment
|
||||||
|
void ProgressBar::SetStepIncrement(int inc)
|
||||||
|
{
|
||||||
|
this->SendMessage(PBM_SETSTEP, inc, 0 /*must be 0. Not used*/);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///Steps the progress bar forward once. Default step is 10
|
||||||
|
void ProgressBar::Step()
|
||||||
|
{
|
||||||
|
this->SendMessage(PBM_STEPIT, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
82
src/win32cpp/ProgressBar.hpp
Normal file
82
src/win32cpp/ProgressBar.hpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// License Agreement:
|
||||||
|
//
|
||||||
|
// The following are Copyright © 2007, Casey Langen
|
||||||
|
//
|
||||||
|
// Sources and Binaries of: win32cpp
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer in the
|
||||||
|
// documentation and/or other materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// * Neither the name of the author nor the names of other contributors may
|
||||||
|
// be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include <win32cpp/Window.hpp>
|
||||||
|
|
||||||
|
namespace win32cpp {
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class ProgressBar; // forward decl
|
||||||
|
|
||||||
|
///\brief
|
||||||
|
///A progress bar.
|
||||||
|
class ProgressBar: public Window
|
||||||
|
{
|
||||||
|
private: // types
|
||||||
|
typedef Window base;
|
||||||
|
|
||||||
|
public: // constructors, methods
|
||||||
|
/*ctor*/ ProgressBar(int width, int height);
|
||||||
|
/*dtor*/ ~ProgressBar();
|
||||||
|
|
||||||
|
void SetMarqueeStyle();
|
||||||
|
void SetSmoothStyle();
|
||||||
|
void SetVerticalStyle();
|
||||||
|
void StartMarquee(bool set, unsigned int delay);
|
||||||
|
DWORD SetRange(unsigned int min, unsigned int max);
|
||||||
|
void SetPos(int pos);
|
||||||
|
void SetStepIncrement(int inc);
|
||||||
|
void Step();
|
||||||
|
|
||||||
|
protected: // methods
|
||||||
|
virtual HWND Create(Window* parent);
|
||||||
|
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
protected: // instance data
|
||||||
|
uistring caption;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
DWORD styleEx;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //win32cpp
|
@ -75,6 +75,7 @@ HCURSOR Splitter::sArrowCursor = ::LoadCursor(0, MAKEINTRESOURCE(IDC_ARROW));
|
|||||||
, anchor(direction == SplitColumn ? AnchorLeft : AnchorTop)
|
, anchor(direction == SplitColumn ? AnchorLeft : AnchorTop)
|
||||||
, minAnchorSize(-1)
|
, minAnchorSize(-1)
|
||||||
, maxAnchorSize(-1)
|
, maxAnchorSize(-1)
|
||||||
|
, sizeFromMouse(-1)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,37 +194,63 @@ const Window* Splitter::Child2()
|
|||||||
return this->child2;
|
return this->child2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Splitter::Layout(int child1Size)
|
void Splitter::LayoutFromMouse()
|
||||||
{
|
{
|
||||||
|
Rect clientRect = this->ClientRect();
|
||||||
|
int clientSize = (this->direction == SplitRow
|
||||||
|
? clientRect.size.height
|
||||||
|
: clientRect.size.width);
|
||||||
|
|
||||||
|
bool child1IsAnchor = (this->anchor == AnchorLeft || this->anchor == AnchorTop);
|
||||||
|
|
||||||
|
int control1Size = this->sizeFromMouse;
|
||||||
|
int control2Size = clientSize - control1Size - this->gripperSize;
|
||||||
|
control2Size = max(control2Size, 0);
|
||||||
|
|
||||||
|
this->anchorSize = (child1IsAnchor ? control1Size : control2Size);
|
||||||
|
|
||||||
|
// done! set this back for the next call to Layout()
|
||||||
|
this->sizeFromMouse = -1;
|
||||||
|
|
||||||
|
this->Layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Splitter::Layout()
|
||||||
|
{
|
||||||
|
if (this->sizeFromMouse != -1)
|
||||||
|
{
|
||||||
|
this->LayoutFromMouse();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Rect clientRect = this->ClientRect();
|
Rect clientRect = this->ClientRect();
|
||||||
//
|
//
|
||||||
int clientSize = (this->direction == SplitRow
|
int clientSize = (this->direction == SplitRow
|
||||||
? clientRect.size.height
|
? clientRect.size.height
|
||||||
: clientRect.size.width);
|
: clientRect.size.width);
|
||||||
|
|
||||||
int anchorSize = (child1Size == -1 ? this->anchorSize : child1Size);
|
int splitterPos = this->anchorSize;
|
||||||
//
|
//
|
||||||
if (anchorSize <= -1)
|
if (splitterPos <= -1)
|
||||||
{
|
{
|
||||||
anchorSize = (clientSize / 2);
|
splitterPos = (clientSize / 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// don't allow the split to go beyond the window boundries
|
// don't allow the split to go beyond the window boundries
|
||||||
anchorSize = min(anchorSize, clientSize - this->gripperSize);
|
splitterPos = min(splitterPos, clientSize - this->gripperSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// size the windows in their split direction
|
// size the windows in their split direction
|
||||||
bool child1IsAnchor = (this->anchor == AnchorLeft || this->anchor == AnchorTop);
|
bool child1IsAnchor = (this->anchor == AnchorLeft || this->anchor == AnchorTop);
|
||||||
child1IsAnchor |= (child1Size != -1);
|
|
||||||
|
|
||||||
if (this->minAnchorSize >= 0) anchorSize = max(this->minAnchorSize, anchorSize);
|
if (this->minAnchorSize >= 0) splitterPos = max(this->minAnchorSize, splitterPos);
|
||||||
if (this->maxAnchorSize >= 0) anchorSize = min(this->maxAnchorSize, anchorSize);
|
if (this->maxAnchorSize >= 0) splitterPos = min(this->maxAnchorSize, splitterPos);
|
||||||
|
|
||||||
int nonAnchorSize = clientSize - (anchorSize + this->gripperSize);
|
int nonAnchorSize = clientSize - (splitterPos + this->gripperSize);
|
||||||
//
|
//
|
||||||
int control1Size = child1IsAnchor ? anchorSize : nonAnchorSize;
|
int control1Size = child1IsAnchor ? splitterPos : nonAnchorSize;
|
||||||
int control2Size = child1IsAnchor ? nonAnchorSize : anchorSize;
|
int control2Size = child1IsAnchor ? nonAnchorSize : splitterPos;
|
||||||
|
|
||||||
if (this->direction == SplitColumn)
|
if (this->direction == SplitColumn)
|
||||||
{
|
{
|
||||||
@ -238,9 +265,18 @@ void Splitter::Layout(int child1Size)
|
|||||||
child2Frame->MoveTo(clientRect.location.x, control1Size + this->gripperSize);
|
child2Frame->MoveTo(clientRect.location.x, control1Size + this->gripperSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child1Size != -1)
|
// remember our splitter rect
|
||||||
|
if (this->direction == SplitColumn)
|
||||||
{
|
{
|
||||||
this->anchorSize = anchorSize;
|
this->splitRect = Rect(
|
||||||
|
Point(control1Size, 0),
|
||||||
|
Size(this->gripperSize, clientRect.size.height));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->splitRect = Rect(
|
||||||
|
Point(0, control1Size),
|
||||||
|
Size(clientRect.size.width, this->gripperSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,9 +357,10 @@ void Splitter::OnMouseMoved(MouseEventFlags flags, const Point& location)
|
|||||||
// do this because we may be redrawing complex child controls (including other
|
// do this because we may be redrawing complex child controls (including other
|
||||||
// splitters) unnecessarily.
|
// splitters) unnecessarily.
|
||||||
RedrawLock redrawLock(Application::Instance().MainWindow());
|
RedrawLock redrawLock(Application::Instance().MainWindow());
|
||||||
this->Layout(position);
|
this->sizeFromMouse = position;
|
||||||
|
this->Layout();
|
||||||
}
|
}
|
||||||
else if ( ! ::PointInRect(this->CursorPosition(), this->SplitterRect()))
|
else if ( ! ::PointInRect(this->CursorPosition(), this->splitRect))
|
||||||
{
|
{
|
||||||
this->EndMouseCapture();
|
this->EndMouseCapture();
|
||||||
}
|
}
|
||||||
@ -343,8 +380,11 @@ void Splitter::OnMouseButtonDown(MouseEventFlags flags, const Point& location
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (::PointInRect(this->CursorPosition(), this->splitRect))
|
||||||
|
{
|
||||||
this->isDragging = true;
|
this->isDragging = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Splitter::OnMouseExit()
|
void Splitter::OnMouseExit()
|
||||||
{
|
{
|
||||||
@ -356,38 +396,6 @@ void Splitter::OnMouseEnter()
|
|||||||
this->BeginMouseCapture();
|
this->BeginMouseCapture();
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect Splitter::SplitterRect()
|
|
||||||
{
|
|
||||||
Rect splitterRect;
|
|
||||||
|
|
||||||
bool child1IsAnchor = (this->anchor == AnchorLeft || this->anchor == AnchorTop);
|
|
||||||
bool isHoriz = (this->direction == SplitColumn);
|
|
||||||
|
|
||||||
int clientSize = isHoriz
|
|
||||||
? this->WindowSize().height
|
|
||||||
: this->WindowSize().width;
|
|
||||||
|
|
||||||
splitterRect.size = Size(
|
|
||||||
isHoriz ? this->gripperSize : clientSize,
|
|
||||||
isHoriz ? clientSize : this->gripperSize);
|
|
||||||
|
|
||||||
int nonAnchorSize = clientSize - (this->anchorSize + this->gripperSize);
|
|
||||||
int location = child1IsAnchor ? this->anchorSize : nonAnchorSize;
|
|
||||||
|
|
||||||
if (location == -1)
|
|
||||||
{
|
|
||||||
location = (isHoriz
|
|
||||||
? this->WindowSize().width
|
|
||||||
: this->WindowSize().height) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
splitterRect.location = Point(
|
|
||||||
isHoriz ? location : 0,
|
|
||||||
isHoriz ? 0 : location);
|
|
||||||
|
|
||||||
return splitterRect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Splitter::OnMouseButtonUp(MouseEventFlags flags, const Point& location)
|
void Splitter::OnMouseButtonUp(MouseEventFlags flags, const Point& location)
|
||||||
{
|
{
|
||||||
this->isDragging = false;
|
this->isDragging = false;
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <win32cpp/Container.hpp>
|
#include <win32cpp/Container.hpp>
|
||||||
|
#include <win32cpp/ILayout.hpp>
|
||||||
|
|
||||||
namespace win32cpp {
|
namespace win32cpp {
|
||||||
|
|
||||||
@ -85,7 +86,7 @@ const int DisableConstraint = -1;
|
|||||||
///children stationary or "anchored," while allowing the other to be resized
|
///children stationary or "anchored," while allowing the other to be resized
|
||||||
///to fill the new space. The anchor can be set via Splitter::SetAnchor by
|
///to fill the new space. The anchor can be set via Splitter::SetAnchor by
|
||||||
///specifying a win32cpp::AnchorDirection.
|
///specifying a win32cpp::AnchorDirection.
|
||||||
class Splitter: public Panel
|
class Splitter: public Panel, public ILayout
|
||||||
{
|
{
|
||||||
private: // types
|
private: // types
|
||||||
typedef Panel base;
|
typedef Panel base;
|
||||||
@ -109,7 +110,6 @@ public: // methods
|
|||||||
|
|
||||||
protected: // methods
|
protected: // methods
|
||||||
void SetSizeCursor();
|
void SetSizeCursor();
|
||||||
Rect SplitterRect();
|
|
||||||
int AnchorSizeFromMouse(int splitPosition, const Size& newSize);
|
int AnchorSizeFromMouse(int splitPosition, const Size& newSize);
|
||||||
void BeginMouseCapture();
|
void BeginMouseCapture();
|
||||||
void EndMouseCapture();
|
void EndMouseCapture();
|
||||||
@ -117,7 +117,8 @@ protected: // methods
|
|||||||
// overrides
|
// overrides
|
||||||
virtual bool AddChildWindow(Window* window);
|
virtual bool AddChildWindow(Window* window);
|
||||||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
virtual void Layout(int child1Size = -1);
|
virtual void Layout();
|
||||||
|
virtual void LayoutFromMouse();
|
||||||
virtual void OnResized(const Size& newSize);
|
virtual void OnResized(const Size& newSize);
|
||||||
virtual void OnMouseMoved(MouseEventFlags flags, const Point& location);
|
virtual void OnMouseMoved(MouseEventFlags flags, const Point& location);
|
||||||
virtual void OnMouseButtonDown(MouseEventFlags flags, const Point& location);
|
virtual void OnMouseButtonDown(MouseEventFlags flags, const Point& location);
|
||||||
@ -131,9 +132,11 @@ private: // instance data
|
|||||||
Frame *child1Frame, *child2Frame;
|
Frame *child1Frame, *child2Frame;
|
||||||
int gripperSize, anchorSize;
|
int gripperSize, anchorSize;
|
||||||
int minAnchorSize, maxAnchorSize;
|
int minAnchorSize, maxAnchorSize;
|
||||||
|
int sizeFromMouse;
|
||||||
bool isDragging, isSizable;
|
bool isDragging, isSizable;
|
||||||
SplitDirection direction;
|
SplitDirection direction;
|
||||||
AnchorDirection anchor;
|
AnchorDirection anchor;
|
||||||
|
Rect splitRect;
|
||||||
|
|
||||||
private: // class data
|
private: // class data
|
||||||
static HCURSOR sHSizeCursor, sVSizeCursor, sArrowCursor;
|
static HCURSOR sHSizeCursor, sVSizeCursor, sArrowCursor;
|
||||||
|
@ -674,7 +674,7 @@ bool Window::MoveTo(const Point& location)
|
|||||||
location.y,
|
location.y,
|
||||||
windowRect.right - windowRect.left,
|
windowRect.right - windowRect.left,
|
||||||
windowRect.bottom - windowRect.top,
|
windowRect.bottom - windowRect.top,
|
||||||
TRUE);
|
this->Visible());
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@ -732,7 +732,7 @@ bool Window::Resize(const Size& size)
|
|||||||
topLeft.y,
|
topLeft.y,
|
||||||
saneSize.width,
|
saneSize.width,
|
||||||
saneSize.height,
|
saneSize.height,
|
||||||
TRUE);
|
this->Visible());
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
@ -791,11 +791,20 @@ bool Window::SetCaption(const uistring& caption)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this->windowHandle) && (::SetWindowText(this->windowHandle, caption.c_str())))
|
if (this->windowHandle)
|
||||||
|
{
|
||||||
|
BOOL success = (BOOL) ::SendMessage(
|
||||||
|
this->windowHandle,
|
||||||
|
WM_SETTEXT,
|
||||||
|
0,
|
||||||
|
(LPARAM) caption.c_str());
|
||||||
|
|
||||||
|
if (success)
|
||||||
{
|
{
|
||||||
this->OnCaptionChanged();
|
this->OnCaptionChanged();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1087,6 +1096,7 @@ void Window::SetVisible(bool visible)
|
|||||||
if (this->Handle())
|
if (this->Handle())
|
||||||
{
|
{
|
||||||
::ShowWindow(this->Handle(), visible ? SW_SHOW : SW_HIDE);
|
::ShowWindow(this->Handle(), visible ? SW_SHOW : SW_HIDE);
|
||||||
|
this->OnVisibilityChangedBase(visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,6 +1405,13 @@ bool Window::OnCharBase(VirtualKeyCode keyCode, KeyEventFlags flags)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Window::OnVisibilityChangedBase(bool visible)
|
||||||
|
{
|
||||||
|
this->OnVisibilityChanged(visible);
|
||||||
|
EMIT_SIGNAL_IF_NOT_SUPPRESSED(this->VisibilityChanged, this, visible);
|
||||||
|
}
|
||||||
|
|
||||||
void Window::OnThemeChanged()
|
void Window::OnThemeChanged()
|
||||||
{
|
{
|
||||||
// If we're the first window to notice the theme change then update
|
// If we're the first window to notice the theme change then update
|
||||||
|
@ -83,6 +83,7 @@ enum MouseEventFlags
|
|||||||
/*! */ typedef sigslot::signal2<Window* /*old*/, Window* /*new*/> ParentChangedEvent;
|
/*! */ typedef sigslot::signal2<Window* /*old*/, Window* /*new*/> ParentChangedEvent;
|
||||||
/*! */ typedef sigslot::signal1<unsigned int> TimerEvent;
|
/*! */ typedef sigslot::signal1<unsigned int> TimerEvent;
|
||||||
/*! */ typedef sigslot::signal3<Window*, VirtualKeyCode, KeyEventFlags> KeyEvent;
|
/*! */ typedef sigslot::signal3<Window*, VirtualKeyCode, KeyEventFlags> KeyEvent;
|
||||||
|
/*! */ typedef sigslot::signal2<Window*, bool> VisibilityChangedEvent;
|
||||||
|
|
||||||
///\brief
|
///\brief
|
||||||
///Window is the abstract base class for all controls.
|
///Window is the abstract base class for all controls.
|
||||||
@ -173,6 +174,8 @@ public: // events
|
|||||||
///\brief Emitted when a control has requested to focus the previous control. This
|
///\brief Emitted when a control has requested to focus the previous control. This
|
||||||
///generally shouldn't be handled explicitly unless absolutely necessary.
|
///generally shouldn't be handled explicitly unless absolutely necessary.
|
||||||
FocusEvent RequestFocusPrev;
|
FocusEvent RequestFocusPrev;
|
||||||
|
///\brief Emitted when a Window's visibility has changed
|
||||||
|
VisibilityChangedEvent VisibilityChanged;
|
||||||
|
|
||||||
public: // ctor, dtor
|
public: // ctor, dtor
|
||||||
/*ctor*/ Window();
|
/*ctor*/ Window();
|
||||||
@ -250,6 +253,7 @@ protected: // methods
|
|||||||
bool OnKeyDownBase(VirtualKeyCode keyCode, KeyEventFlags flags);
|
bool OnKeyDownBase(VirtualKeyCode keyCode, KeyEventFlags flags);
|
||||||
bool OnKeyUpBase(VirtualKeyCode keyCode, KeyEventFlags flags);
|
bool OnKeyUpBase(VirtualKeyCode keyCode, KeyEventFlags flags);
|
||||||
bool OnCharBase(VirtualKeyCode keyCode, KeyEventFlags flags);
|
bool OnCharBase(VirtualKeyCode keyCode, KeyEventFlags flags);
|
||||||
|
void OnVisibilityChangedBase(bool visible);
|
||||||
|
|
||||||
// win32 event wrappers (virtual methods, for derived class use)
|
// win32 event wrappers (virtual methods, for derived class use)
|
||||||
virtual void OnDestroyed() { }
|
virtual void OnDestroyed() { }
|
||||||
@ -277,6 +281,7 @@ protected: // methods
|
|||||||
virtual void OnRequestFocusPrev();
|
virtual void OnRequestFocusPrev();
|
||||||
virtual void OnRequestFocusNext();
|
virtual void OnRequestFocusNext();
|
||||||
virtual HBRUSH OnControlColor(HDC hdc);
|
virtual HBRUSH OnControlColor(HDC hdc);
|
||||||
|
virtual void OnVisibilityChanged(bool visible) { }
|
||||||
|
|
||||||
// window proc related
|
// window proc related
|
||||||
virtual LRESULT PreWindowProcBase(UINT message, WPARAM wParam, LPARAM lParam, bool& discardMessage);
|
virtual LRESULT PreWindowProcBase(UINT message, WPARAM wParam, LPARAM lParam, bool& discardMessage);
|
||||||
|
@ -332,6 +332,14 @@
|
|||||||
RelativePath=".\ListView.hpp"
|
RelativePath=".\ListView.hpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ProgressBar.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\ProgressBar.hpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Window.cpp"
|
RelativePath=".\Window.cpp"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user