mirror of
https://github.com/clangen/musikcube.git
synced 2025-03-02 22:13:32 +00:00
Added a "Connected users" window to musikServer.
Started on playlist support.
This commit is contained in:
parent
8810ec6afe
commit
28e672ab40
@ -55,6 +55,7 @@ Library::Base::Base(utfstring identifier)
|
||||
:identifier(identifier)
|
||||
,queueCallbackStarted(false)
|
||||
,exit(false)
|
||||
,userId(1)
|
||||
{
|
||||
}
|
||||
|
||||
@ -694,3 +695,11 @@ void Library::Base::CreateDatabase(db::Connection &db){
|
||||
utfstring Library::Base::BasePath(){
|
||||
return UTF("");
|
||||
}
|
||||
|
||||
LibraryPtr Library::Base::GetSelfPtr(){
|
||||
if(LibraryPtr thisPtr = this->self.lock()){
|
||||
return thisPtr;
|
||||
}
|
||||
return LibraryPtr();
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,9 @@ class Base : boost::noncopyable{
|
||||
boost::mutex libraryMutex;
|
||||
LibraryWeakPtr self;
|
||||
|
||||
LibraryPtr GetSelfPtr();
|
||||
|
||||
int userId;
|
||||
|
||||
};
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "pch.hpp"
|
||||
#include <core/Query/Playlists.h>
|
||||
#include <core/Library/Base.h>
|
||||
#include <core/tracklist/Playlist.h>
|
||||
|
||||
using namespace musik::core;
|
||||
|
||||
@ -58,6 +59,18 @@ Query::Playlists::~Playlists(void){
|
||||
|
||||
bool Query::Playlists::ParseQuery(Library::Base *library,db::Connection &db){
|
||||
|
||||
db::Statement stmt("SELECT id,name FROM playlists WHERE user_id=?",db);
|
||||
|
||||
while(stmt.Step()==db::Row){
|
||||
tracklist::Ptr playlist( new tracklist::Playlist(
|
||||
stmt.ColumnInt(0),
|
||||
stmt.ColumnTextUTF(1),
|
||||
library->GetSelfPtr()
|
||||
) );
|
||||
|
||||
this->tracklistVector.push_back(playlist);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -73,6 +86,19 @@ Query::Ptr Query::Playlists::copy() const{
|
||||
}
|
||||
|
||||
bool Query::Playlists::RunCallbacks(Library::Base *library){
|
||||
return true;
|
||||
bool bReturn(false);
|
||||
{
|
||||
boost::mutex::scoped_lock lock(library->libraryMutex);
|
||||
if( (this->status & Status::Ended)!=0){
|
||||
// If the query is finished, this function should return true to report that it is finished.
|
||||
bReturn = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(bReturn){
|
||||
this->PlaylistList(this->tracklistVector);
|
||||
}
|
||||
|
||||
return bReturn;
|
||||
}
|
||||
|
||||
|
@ -36,16 +36,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <sigslot/sigslot.h>
|
||||
|
||||
#include <core/config.h>
|
||||
#include <core/Query/Base.h>
|
||||
#include <core/tracklist/IRandomAccess.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Forward declarations
|
||||
//////////////////////////////////////////////////////////////
|
||||
@ -55,31 +45,46 @@ namespace musik{ namespace core{
|
||||
}
|
||||
} }
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik{ namespace core{
|
||||
namespace Query{
|
||||
#include <core/config.h>
|
||||
#include <core/Query/Base.h>
|
||||
#include <core/tracklist/IRandomAccess.h>
|
||||
|
||||
class Playlists : public Query::Base{
|
||||
public:
|
||||
Playlists(void);
|
||||
~Playlists(void);
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <vector>
|
||||
#include <sigslot/sigslot.h>
|
||||
|
||||
protected:
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
bool RunCallbacks(Library::Base *library);
|
||||
namespace musik{ namespace core{ namespace Query{
|
||||
|
||||
friend class Library::Base;
|
||||
friend class Library::LocalDB;
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
virtual bool ParseQuery(Library::Base *library,db::Connection &db);
|
||||
class Playlists : public Query::Base{
|
||||
public:
|
||||
Playlists(void);
|
||||
~Playlists(void);
|
||||
|
||||
Ptr copy() const;
|
||||
typedef std::vector<musik::core::tracklist::Ptr> TracklistVector;
|
||||
typedef sigslot::signal1<TracklistVector> PlaylistListEvent;
|
||||
|
||||
private:
|
||||
PlaylistListEvent PlaylistList;
|
||||
|
||||
};
|
||||
protected:
|
||||
|
||||
}
|
||||
} }
|
||||
bool RunCallbacks(Library::Base *library);
|
||||
virtual bool ParseQuery(Library::Base *library,db::Connection &db);
|
||||
|
||||
Ptr copy() const;
|
||||
|
||||
private:
|
||||
TracklistVector tracklistVector;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
} } }
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -220,11 +220,13 @@ bool Server::AddUserSession(server::UserSessionPtr userSession){
|
||||
}
|
||||
|
||||
bool Server::RemoveUserSession(server::UserSessionPtr userSession){
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->serverMutex);
|
||||
this->connectedUsers.erase(userSession->UniqueId());
|
||||
if(userSession){
|
||||
{
|
||||
boost::mutex::scoped_lock lock(this->serverMutex);
|
||||
this->connectedUsers.erase(userSession->UniqueId());
|
||||
}
|
||||
this->UserSessionsUpdated();
|
||||
}
|
||||
this->UserSessionsUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -240,6 +240,14 @@
|
||||
RelativePath=".\tracklist\IRandomAccess.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tracklist\Playlist.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tracklist\Playlist.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tracklist\Standard.cpp"
|
||||
>
|
||||
|
@ -109,7 +109,9 @@ void Connection::ReadThread(){
|
||||
UserPtr user = this->server->GetUser(musik::core::ConvertUTF16(userNode.Attributes()["username"]));
|
||||
if(user){
|
||||
// Create a new usersession
|
||||
UserSessionPtr userSession( new UserSession(user,this->salt) );
|
||||
|
||||
boost::asio::ip::tcp::endpoint endpoint = this->socket.remote_endpoint();
|
||||
UserSessionPtr userSession( new UserSession(user,this->salt,endpoint.address().to_string()) );
|
||||
|
||||
// Check if encrypted password is the same
|
||||
if( musik::core::Crypt::Encrypt(UTF_TO_UTF8(user->Password()),this->salt)==userNode.Content() ){
|
||||
@ -330,6 +332,7 @@ void Connection::Exit(){
|
||||
if(this->socket.is_open()){
|
||||
this->socket.close();
|
||||
}
|
||||
this->server->RemoveUserSession(this->userSession);
|
||||
}
|
||||
this->exit = true;
|
||||
}
|
||||
|
@ -42,9 +42,10 @@ using namespace musik::core::server;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UserSession::UserSession(UserPtr& user,std::string uniqueId)
|
||||
UserSession::UserSession(UserPtr& user,std::string uniqueId,std::string ip)
|
||||
:user(user)
|
||||
,uniqueId(uniqueId)
|
||||
,ip(ip)
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,3 +57,7 @@ std::string UserSession::UniqueId(){
|
||||
return this->uniqueId;
|
||||
}
|
||||
|
||||
std::string UserSession::IP(){
|
||||
return this->ip;
|
||||
}
|
||||
|
||||
|
@ -51,15 +51,17 @@ namespace musik{ namespace core{ namespace server{
|
||||
class UserSession
|
||||
{
|
||||
public:
|
||||
UserSession(UserPtr& user,std::string uniqueId);
|
||||
UserSession(UserPtr& user,std::string uniqueId,std::string ip);
|
||||
~UserSession(void);
|
||||
|
||||
std::string UniqueId();
|
||||
std::string IP();
|
||||
|
||||
protected:
|
||||
UserPtr user;
|
||||
protected:
|
||||
|
||||
std::string uniqueId;
|
||||
std::string ip;
|
||||
|
||||
|
||||
};
|
||||
|
68
src/core/tracklist/Playlist.cpp
Normal file
68
src/core/tracklist/Playlist.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, mC2 team
|
||||
//
|
||||
// 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 <core/tracklist/Playlist.h>
|
||||
|
||||
#include <core/Query/PlaylistLoad.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace musik::core::tracklist;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Playlist::Playlist(int id,utfstring name,musik::core::LibraryPtr library)
|
||||
:Standard()
|
||||
,id(0)
|
||||
{
|
||||
this->SetLibrary(library);
|
||||
|
||||
// Start by creating a query that loads the tracks
|
||||
}
|
||||
|
||||
|
||||
Playlist::~Playlist(void){
|
||||
}
|
||||
|
||||
utfstring Playlist::Name(){
|
||||
return this->name;
|
||||
}
|
||||
|
||||
int Playlist::Id(){
|
||||
return this->id;
|
||||
}
|
||||
|
65
src/core/tracklist/Playlist.h
Normal file
65
src/core/tracklist/Playlist.h
Normal file
@ -0,0 +1,65 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2008, mC2 team
|
||||
//
|
||||
// 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 <core/tracklist/Standard.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik{ namespace core{ namespace tracklist {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class Playlist : public Standard {
|
||||
|
||||
public:
|
||||
Playlist(int id,utfstring name,musik::core::LibraryPtr library);
|
||||
~Playlist(void);
|
||||
|
||||
utfstring Name();
|
||||
int Id();
|
||||
|
||||
private:
|
||||
int id;
|
||||
utfstring name;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
} } } // musik::core::tracklist
|
||||
//////////////////////////////////////////////////////////////////////////////
|
@ -52,77 +52,73 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik{ namespace core{
|
||||
namespace tracklist {
|
||||
namespace musik{ namespace core{ namespace tracklist {
|
||||
|
||||
class Standard : public IRandomAccess, public sigslot::has_slots<> {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
class Standard : public IRandomAccess, public sigslot::has_slots<> {
|
||||
|
||||
public:
|
||||
|
||||
// typedef boost::shared_ptr<Standard> Ptr;
|
||||
public:
|
||||
Standard(void);
|
||||
~Standard(void);
|
||||
|
||||
Standard(void);
|
||||
~Standard(void);
|
||||
|
||||
musik::core::TrackPtr CurrentTrack();
|
||||
musik::core::TrackPtr NextTrack();
|
||||
musik::core::TrackPtr PreviousTrack();
|
||||
musik::core::TrackPtr CurrentTrack();
|
||||
musik::core::TrackPtr NextTrack();
|
||||
musik::core::TrackPtr PreviousTrack();
|
||||
|
||||
|
||||
virtual void SetCurrentPosition(int position);
|
||||
virtual int CurrentPosition();
|
||||
virtual void SetCurrentPosition(int position);
|
||||
virtual int CurrentPosition();
|
||||
|
||||
virtual int Size();
|
||||
virtual int Size();
|
||||
|
||||
virtual musik::core::TrackPtr operator [](int position);
|
||||
virtual musik::core::TrackPtr TrackWithMetadata(int position);
|
||||
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 void SetLibrary(musik::core::LibraryPtr setLibrary);
|
||||
virtual musik::core::LibraryPtr Library();
|
||||
|
||||
virtual bool CopyTracks(musik::core::tracklist::Ptr tracklist);
|
||||
virtual bool AppendTracks(musik::core::tracklist::Ptr tracklist);
|
||||
virtual bool CopyTracks(musik::core::tracklist::Ptr tracklist);
|
||||
virtual bool AppendTracks(musik::core::tracklist::Ptr tracklist);
|
||||
|
||||
virtual void AppendTrack(musik::core::TrackPtr track);
|
||||
virtual void Clear();
|
||||
virtual void AppendTrack(musik::core::TrackPtr track);
|
||||
virtual void Clear();
|
||||
|
||||
virtual void AddRequestedMetakey(const char* metakey);
|
||||
virtual void RemoveRequestedMetakey(const char* metakey);
|
||||
virtual void AddRequestedMetakey(const char* metakey);
|
||||
virtual void RemoveRequestedMetakey(const char* metakey);
|
||||
|
||||
virtual UINT64 Duration();
|
||||
virtual UINT64 Filesize();
|
||||
virtual UINT64 Duration();
|
||||
virtual UINT64 Filesize();
|
||||
|
||||
virtual void HintNumberOfRows(int rows);
|
||||
virtual void HintNumberOfRows(int rows);
|
||||
|
||||
virtual void ConnectToQuery(musik::core::Query::ListBase &listQuery);
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
virtual void ConnectToQuery(musik::core::Query::ListBase &listQuery);
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
void LoadTrack(int position);
|
||||
bool QueryForTrack(int position);
|
||||
void OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear);
|
||||
void OnTracksMetaFromQuery(musik::core::TrackVector *metaTracks);
|
||||
void OnTracksInfoFromQuery(UINT64 tracks,UINT64 duration,UINT64 filesize);
|
||||
void LoadTrack(int position);
|
||||
bool QueryForTrack(int position);
|
||||
void OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear);
|
||||
void OnTracksMetaFromQuery(musik::core::TrackVector *metaTracks);
|
||||
void OnTracksInfoFromQuery(UINT64 tracks,UINT64 duration,UINT64 filesize);
|
||||
|
||||
std::set<std::string> requestedMetaKeys;
|
||||
std::set<std::string> requestedMetaKeys;
|
||||
|
||||
int currentPosition;
|
||||
int hintedRows;
|
||||
int currentPosition;
|
||||
int hintedRows;
|
||||
|
||||
musik::core::LibraryPtr library;
|
||||
musik::core::TrackVector tracks;
|
||||
musik::core::Query::TrackMetadata trackQuery;
|
||||
musik::core::LibraryPtr library;
|
||||
musik::core::TrackVector tracks;
|
||||
musik::core::Query::TrackMetadata trackQuery;
|
||||
|
||||
typedef boost::bimap<int,musik::core::TrackPtr> TrackCache;
|
||||
TrackCache trackCache;
|
||||
typedef boost::bimap<int,musik::core::TrackPtr> TrackCache;
|
||||
TrackCache trackCache;
|
||||
|
||||
UINT64 infoDuration;
|
||||
UINT64 infoFilesize;
|
||||
UINT64 infoDuration;
|
||||
UINT64 infoFilesize;
|
||||
};
|
||||
|
||||
// bool InCache(int position);
|
||||
// bool InCache(musik::core::TrackPtr track);
|
||||
};
|
||||
}
|
||||
} } // musik::core
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
} } } // musik::core::tracklist
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -71,6 +71,7 @@ void MainMenuController::ConnectMenuHandlers()
|
||||
this->helpAbout->Activated.connect(this, &MainMenuController::OnHelpAbout);
|
||||
this->fileAddLibraryLocal->Activated.connect(this,&MainMenuController::OnAddLibraryLocal);
|
||||
this->fileAddLibraryRemote->Activated.connect(this,&MainMenuController::OnAddLibraryRemote);
|
||||
this->fileNewPlaylist->Activated.connect(this,&MainMenuController::OnNewPlaylist);
|
||||
}
|
||||
|
||||
void MainMenuController::OnFileExit(MenuItemRef menuItem)
|
||||
@ -138,6 +139,10 @@ void MainMenuController::OnHelpAbout(MenuItemRef menuItem)
|
||||
MB_ICONINFORMATION | MB_OK);
|
||||
}
|
||||
|
||||
void MainMenuController::OnNewPlaylist(MenuItemRef menuItem){
|
||||
}
|
||||
|
||||
|
||||
MenuRef MainMenuController::CreateMenu()
|
||||
{
|
||||
// main menu
|
||||
@ -156,13 +161,14 @@ MenuRef MainMenuController::CreateMenu()
|
||||
//
|
||||
this->file->SetSubMenu(this->fileMenu);
|
||||
|
||||
MenuItemRef addLibraryMenu = fileItems.Append(MenuItem::Create(_(_T("&New Library"))));
|
||||
MenuRef addLibrarySubmenu = Menu::Create();
|
||||
this->fileAddLibraryLocal = addLibrarySubmenu->Items().Append(MenuItem::Create(_(_T("&Local library"))));
|
||||
this->fileAddLibraryRemote = addLibrarySubmenu->Items().Append(MenuItem::Create(_(_T("&Remote library"))));
|
||||
|
||||
MenuItemRef addLibraryMenu = fileItems.Append(MenuItem::Create(_(_T("&Add Library"))));
|
||||
addLibraryMenu->SetSubMenu(addLibrarySubmenu);
|
||||
|
||||
this->fileNewPlaylist = fileItems.Append(MenuItem::Create(_(_T("&New Playlist"))));
|
||||
|
||||
this->fileExit = fileItems.Append(MenuItem::Create(_(_T("E&xit"))));
|
||||
|
||||
// help menu
|
||||
|
@ -72,13 +72,13 @@ class MainMenuController: public EventHandler
|
||||
void OnHelpAbout(MenuItemRef menuItem);
|
||||
void OnAddLibraryLocal(MenuItemRef menuItem);
|
||||
void OnAddLibraryRemote(MenuItemRef menuItem);
|
||||
|
||||
void OnNewPlaylist(MenuItemRef menuItem);
|
||||
|
||||
private:
|
||||
TopLevelWindow& mainWindow;
|
||||
MenuRef mainMenu, fileMenu, helpMenu;
|
||||
MenuItemRef file, view, audio, tags, help;
|
||||
MenuItemRef fileExit, helpAbout, fileAddLibraryRemote, fileAddLibraryLocal;
|
||||
MenuItemRef fileExit, helpAbout, fileAddLibraryRemote, fileAddLibraryLocal, fileNewPlaylist;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -188,12 +188,13 @@ void SourcesModel::Load()
|
||||
viewCategory->Add(SettingsItem::Create(this->library));
|
||||
this->AddCategory(viewCategory);
|
||||
|
||||
CategoryRef playlistCategory(new Category(_(_T("Playlists"))));
|
||||
playlistCategory->Add(DummyItem::Create(_(_T("Playlist 1"))));
|
||||
this->playlistCategory.reset(new Category(_(_T("Playlists"))));
|
||||
/* playlistCategory->Add(DummyItem::Create(_(_T("Playlist 1"))));
|
||||
playlistCategory->Add(DummyItem::Create(_(_T("Playlist 2"))));
|
||||
playlistCategory->Add(DummyItem::Create(_(_T("Dynamic Playlist 3"))));
|
||||
playlistCategory->Add(DummyItem::Create(_(_T("Dynamic Playlist 4"))));
|
||||
this->AddCategory(playlistCategory);
|
||||
playlistCategory->Add(DummyItem::Create(_(_T("Dynamic Playlist 4"))));*/
|
||||
this->AddCategory(this->playlistCategory);
|
||||
|
||||
}
|
||||
|
||||
#define FIND_CATEGORY(list, category) std::find(list.begin(), list.end(), category)
|
||||
|
@ -72,8 +72,9 @@ protected: void OnActiveItemChanged(ItemRef);
|
||||
|
||||
private: ItemRef activeItem;
|
||||
private: CategoryList categories;
|
||||
private: CategoryRef playlistCategory;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} } // musik::cube
|
||||
} } // musik::cube
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <cube/MainWindowController.hpp>
|
||||
#include <win32cpp/Application.hpp>
|
||||
#include <win32cpp/TopLevelWindow.hpp>
|
||||
#include <core/Common.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -52,19 +53,11 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPTSTR commandLi
|
||||
|
||||
// Initialize locale
|
||||
try {
|
||||
Locale::Instance()->SetLocaleDirectory(_T("locales"));
|
||||
uistring appDirectory( musik::core::GetApplicationDirectory() );
|
||||
Locale::Instance()->SetLocaleDirectory(appDirectory);
|
||||
Locale::Instance()->LoadConfig(_T("english"));
|
||||
}
|
||||
catch(win32cpp::Win32Exception& e) {
|
||||
MessageBox(NULL, WidenString(e.Message()).c_str(), _T("Error while initializing locale"), MB_ICONERROR | MB_OK);
|
||||
return -1;
|
||||
}
|
||||
catch(Exception& e) {
|
||||
MessageBox(NULL, WidenString(e.Message()).c_str(), _T("Error while initializing locale"), MB_ICONERROR | MB_OK);
|
||||
return -2;
|
||||
}
|
||||
if(!Locale::Instance()->LoadConfig(_T("english"))) {
|
||||
MessageBox(NULL, _T("Cannot load config!"), _T("Error while initializing locale"), MB_ICONERROR | MB_OK);
|
||||
return -3;
|
||||
catch(...) {
|
||||
}
|
||||
|
||||
// Initialize the main application (mC2.exe)
|
||||
|
216
src/server/ConnectedUsersController.cpp
Normal file
216
src/server/ConnectedUsersController.cpp
Normal file
@ -0,0 +1,216 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2007, mC2 team
|
||||
//
|
||||
// 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 <server/ConnectedUsersController.hpp>
|
||||
#include <server/ConnectedUsersListController.hpp>
|
||||
|
||||
#include <server/MainWindowController.hpp>
|
||||
|
||||
#include <server/resources/resource.h>
|
||||
#include <core/Preferences.h>
|
||||
|
||||
#include <win32cpp/Types.hpp> // uichar, uistring
|
||||
#include <win32cpp/TopLevelWindow.hpp>
|
||||
#include <win32cpp/Application.hpp>
|
||||
#include <win32cpp/ApplicationThread.hpp>
|
||||
#include <win32cpp/ListView.hpp>
|
||||
#include <win32cpp/RedrawLock.hpp>
|
||||
#include <win32cpp/LinearLayout.hpp>
|
||||
#include <win32cpp/Label.hpp>
|
||||
#include <win32cpp/Frame.hpp>
|
||||
#include <win32cpp/TrayIconManager.hpp>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace musik::server;
|
||||
using namespace win32cpp;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*ctor*/ ConnectedUsersController::ConnectedUsersController(TopLevelWindow& mainWindow,musik::core::ServerPtr server)
|
||||
:mainWindow(mainWindow)
|
||||
,server(server)
|
||||
,mainFrame(NULL)
|
||||
,timer(200)
|
||||
,statusLabel(NULL)
|
||||
,listViewController(NULL)
|
||||
{
|
||||
|
||||
this->mainWindow.Created.connect(
|
||||
this, &ConnectedUsersController::OnMainWindowCreated);
|
||||
|
||||
}
|
||||
|
||||
ConnectedUsersController::~ConnectedUsersController()
|
||||
{
|
||||
delete this->listViewController;
|
||||
}
|
||||
|
||||
void ConnectedUsersController::OnMainWindowCreated(Window* window)
|
||||
{
|
||||
|
||||
// Start by setting the icon
|
||||
HICON icon16 = (HICON)LoadImage(Application::Instance(), MAKEINTRESOURCE(IDI_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
|
||||
HICON icon32 = (HICON)LoadImage(Application::Instance(), MAKEINTRESOURCE(IDI_MAINFRAME), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
|
||||
SendMessage( window->Handle(), WM_SETICON, WPARAM( ICON_SMALL ), LPARAM( icon16 ) );
|
||||
SendMessage( window->Handle(), WM_SETICON, WPARAM( ICON_BIG ), LPARAM( icon32 ) );
|
||||
|
||||
|
||||
// Init Tray Icon
|
||||
MenuRef myMenu = Menu::CreatePopup();
|
||||
|
||||
// Create Tray Menu
|
||||
MenuItemRef settingsMenu = myMenu->Items().Append(MenuItem::Create(_T("S&ettings")));
|
||||
MenuItemRef trayExit = myMenu->Items().Append(MenuItem::Create(_T("E&xit")));
|
||||
|
||||
// Bind Exit to handler
|
||||
trayExit->Activated.connect(this, &ConnectedUsersController::OnFileExit);
|
||||
settingsMenu->Activated.connect(this, &ConnectedUsersController::OnSettings);
|
||||
|
||||
UINT uidTrayIcon = Application::Instance().SysTrayManager()->AddIcon(Application::Instance().MainWindow(), icon16);
|
||||
Application::Instance().SysTrayManager()->SetTooltip(uidTrayIcon, _T("musikServer"));
|
||||
Application::Instance().SysTrayManager()->SetPopupMenu(uidTrayIcon, myMenu);
|
||||
Application::Instance().SysTrayManager()->EnableMinimizeToTray(uidTrayIcon);
|
||||
|
||||
{
|
||||
// Set window size and position
|
||||
musik::core::Preferences windowPrefs("ServerUsersWindow");
|
||||
this->mainWindow.MoveTo(windowPrefs.GetInt("x",200), windowPrefs.GetInt("y",200));
|
||||
this->mainWindow.Resize(windowPrefs.GetInt("width",240), windowPrefs.GetInt("height",320));
|
||||
this->mainWindow.SetMinimumSize(Size(240, 320));
|
||||
}
|
||||
|
||||
|
||||
FontRef boldFont(Font::Create());
|
||||
boldFont->SetBold(true);
|
||||
|
||||
|
||||
// Create the layout
|
||||
this->mainFrame = new win32cpp::Frame(NULL,win32cpp::FramePadding(10));
|
||||
win32cpp::LinearLayout *mainRowLayout = new win32cpp::LinearLayout(win32cpp::LinearRowLayout);
|
||||
mainRowLayout->SetSpacing(10);
|
||||
mainRowLayout->SetDefaultChildFill(false);
|
||||
|
||||
// First a "Status" of the server
|
||||
win32cpp::LinearLayout *statusColumnLayout = mainRowLayout->AddChild( new win32cpp::LinearLayout(win32cpp::LinearColumnLayout) );
|
||||
win32cpp::Label *statusHeader = new win32cpp::Label(_T("Server status "));
|
||||
statusHeader->SetFont(boldFont);
|
||||
statusColumnLayout->AddChild( statusHeader );
|
||||
this->statusLabel = statusColumnLayout->AddChild( new win32cpp::Label(_T("")));
|
||||
|
||||
// Second a TabView for the settings
|
||||
win32cpp::ListView *usersList = mainRowLayout->AddChild( new win32cpp::ListView() );
|
||||
mainRowLayout->SetChildFill(usersList,true);
|
||||
mainRowLayout->SetFlexibleChild(usersList);
|
||||
this->listViewController = new musik::server::ConnectedUsersListController(*usersList,this);
|
||||
|
||||
|
||||
this->mainFrame->AddChild(mainRowLayout);
|
||||
this->mainWindow.AddChild(mainFrame);
|
||||
|
||||
// Connect size and position signals
|
||||
this->mainWindow.Resized.connect(this, &ConnectedUsersController::OnResize);
|
||||
this->mainWindow.Destroyed.connect(this, &ConnectedUsersController::OnDestroyed);
|
||||
|
||||
// Start the status timer
|
||||
this->timer.OnTimeout.connect(this,&ConnectedUsersController::UpdateStatus);
|
||||
this->timer.ConnectToWindow(&this->mainWindow);
|
||||
this->timer.Start();
|
||||
|
||||
this->server->UserSessionsUpdated.connect(this,&ConnectedUsersController::UpdateUserlist);
|
||||
|
||||
}
|
||||
|
||||
void ConnectedUsersController::OnResize(Window* window, Size size)
|
||||
{
|
||||
RedrawLock redrawLock(this->mainFrame);
|
||||
this->mainFrame->Resize(this->mainWindow.ClientSize());
|
||||
}
|
||||
|
||||
void ConnectedUsersController::OnDestroyed(Window* window)
|
||||
{
|
||||
Point location( window->Location() );
|
||||
Size size( window->WindowSize() );
|
||||
musik::core::Preferences windowPrefs("ServerUsersWindow");
|
||||
windowPrefs.SetInt("x",location.x);
|
||||
windowPrefs.SetInt("y",location.y);
|
||||
windowPrefs.SetInt("width",size.width);
|
||||
windowPrefs.SetInt("height",size.height);
|
||||
}
|
||||
|
||||
void ConnectedUsersController::UpdateStatus(){
|
||||
if(this->statusLabel && this->server){
|
||||
this->statusLabel->SetCaption( this->server->indexer.GetStatus() );
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectedUsersController::OnFileExit(MenuItemRef menuItem)
|
||||
{
|
||||
Application::Instance().Terminate();
|
||||
}
|
||||
|
||||
void ConnectedUsersController::OnSettings(MenuItemRef menuItem){
|
||||
static bool settingsShowing(false);
|
||||
|
||||
if(!settingsShowing){
|
||||
settingsShowing = true;
|
||||
|
||||
this->mainWindow.Show(SW_SHOWNORMAL);
|
||||
|
||||
TopLevelWindow dialog(_T("Settings"));
|
||||
MainWindowController settingsController(dialog,this->server);
|
||||
dialog.ShowModal(&this->mainWindow);
|
||||
|
||||
this->mainWindow.Show(SW_HIDE);
|
||||
this->mainWindow.Show(SW_MINIMIZE);
|
||||
|
||||
settingsShowing = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectedUsersController::UpdateUserlist(){
|
||||
if(!win32cpp::ApplicationThread::InMainThread()){
|
||||
win32cpp::ApplicationThread::Call0(this,&ConnectedUsersController::UpdateUserlist);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the connected users
|
||||
musik::core::server::UserSessionVector userSessions( this->server->ConnectedUserSessions() );
|
||||
|
||||
}
|
||||
|
94
src/server/ConnectedUsersController.hpp
Normal file
94
src/server/ConnectedUsersController.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2007, mC2 team
|
||||
//
|
||||
// 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
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Forward declare
|
||||
namespace win32cpp{
|
||||
class TopLevelWindow;
|
||||
class Label;
|
||||
class Frame;
|
||||
}
|
||||
namespace musik { namespace server {
|
||||
class MainWindowController;
|
||||
class ConnectedUsersListController;
|
||||
} }
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <core/Server.h>
|
||||
#include <win32cpp/Timer.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace win32cpp;
|
||||
|
||||
namespace musik { namespace server {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ConnectedUsersController : public EventHandler
|
||||
{
|
||||
public:
|
||||
ConnectedUsersController(TopLevelWindow& mainWindow,musik::core::ServerPtr server);
|
||||
~ConnectedUsersController();
|
||||
|
||||
musik::core::ServerPtr server;
|
||||
protected:
|
||||
void OnMainWindowCreated(Window* window);
|
||||
void OnResize(Window* window, Size size);
|
||||
void OnDestroyed(Window* window);
|
||||
void OnFileExit(MenuItemRef menuItem);
|
||||
void OnSettings(MenuItemRef menuItem);
|
||||
|
||||
void UpdateStatus();
|
||||
void UpdateUserlist();
|
||||
|
||||
protected:
|
||||
TopLevelWindow& mainWindow;
|
||||
win32cpp::Label *statusLabel;
|
||||
win32cpp::Frame *mainFrame;
|
||||
|
||||
win32cpp::Timer timer;
|
||||
|
||||
ConnectedUsersListController *listViewController;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} } // musik::server
|
92
src/server/ConnectedUsersListController.cpp
Normal file
92
src/server/ConnectedUsersListController.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2007, mC2 Team
|
||||
//
|
||||
// Sources and Binaries of: mC2
|
||||
//
|
||||
// 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 <server/ConnectedUsersListController.hpp>
|
||||
#include <server/ConnectedUsersListModel.hpp>
|
||||
#include <server/ConnectedUsersController.hpp>
|
||||
|
||||
#include <core/Indexer.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace musik::server;
|
||||
using namespace win32cpp;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConnectedUsersListController::ConnectedUsersListController(win32cpp::ListView &listView,musik::server::ConnectedUsersController *connectedUsersController)
|
||||
: listView(listView)
|
||||
, connectedUsersController(connectedUsersController)
|
||||
{
|
||||
this->model.reset(new ConnectedUsersListModel(this));
|
||||
this->listView.Handle()
|
||||
? this->OnViewCreated(&listView)
|
||||
: this->listView.Created.connect(this, &ConnectedUsersListController::OnViewCreated);
|
||||
}
|
||||
|
||||
|
||||
void ConnectedUsersListController::OnViewCreated(Window* window){
|
||||
this->listView.SetScrollBarVisibility(HorizontalScrollBar, false);
|
||||
|
||||
typedef ListView::Column Column;
|
||||
|
||||
Size clientSize = this->listView.ClientSize();
|
||||
|
||||
this->nameColumn = Column::Create(_T("User"), clientSize.width/2);
|
||||
this->listView.AddColumn(this->nameColumn);
|
||||
this->ipColumn = Column::Create(_T("IP"), clientSize.width/2);
|
||||
this->listView.AddColumn(this->ipColumn);
|
||||
|
||||
this->listView.EnableColumnResizing(false);
|
||||
this->listView.SetModel(this->model);
|
||||
//
|
||||
int itemHeight = this->listView.RowHeight();
|
||||
this->listView.SetRowHeight(max(itemHeight, 17));
|
||||
|
||||
this->listView.Resized.connect(
|
||||
this, &ConnectedUsersListController::OnResized);
|
||||
|
||||
}
|
||||
|
||||
void ConnectedUsersListController::OnResized(Window* window, Size size)
|
||||
{
|
||||
this->listView.SetColumnWidth(this->nameColumn, this->listView.ClientSize().width/2);
|
||||
this->listView.SetColumnWidth(this->ipColumn, this->listView.ClientSize().width/2);
|
||||
}
|
||||
|
78
src/server/ConnectedUsersListController.hpp
Normal file
78
src/server/ConnectedUsersListController.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2007, mC2 Team
|
||||
//
|
||||
// Sources and Binaries of: mC2
|
||||
//
|
||||
// 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/ListView.hpp>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Forward
|
||||
namespace musik { namespace server {
|
||||
class ConnectedUsersController;
|
||||
class ConnectedUsersListModel;
|
||||
} }
|
||||
|
||||
|
||||
|
||||
namespace musik { namespace server {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ConnectedUsersListController : public win32cpp::EventHandler{
|
||||
public:
|
||||
ConnectedUsersListController(win32cpp::ListView &listView,musik::server::ConnectedUsersController *connectedUsersController);
|
||||
private:
|
||||
void OnViewCreated(win32cpp::Window* window);
|
||||
void OnResized(win32cpp::Window* window, win32cpp::Size size);
|
||||
|
||||
win32cpp::ListView& listView;
|
||||
win32cpp::ListView::ModelRef model;
|
||||
|
||||
friend class ConnectedUsersListModel;
|
||||
win32cpp::ListView::ColumnRef nameColumn;
|
||||
win32cpp::ListView::ColumnRef ipColumn;
|
||||
|
||||
musik::server::ConnectedUsersController* connectedUsersController;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} } // musik::cube::settings
|
96
src/server/ConnectedUsersListModel.cpp
Normal file
96
src/server/ConnectedUsersListModel.cpp
Normal file
@ -0,0 +1,96 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2007, mC2 Team
|
||||
//
|
||||
// Sources and Binaries of: mC2
|
||||
//
|
||||
// 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 <server/ConnectedUsersListModel.hpp>
|
||||
#include <server/ConnectedUsersController.hpp>
|
||||
#include <win32cpp/ApplicationThread.hpp>
|
||||
#include <core/Server.h>
|
||||
#include <core/Common.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
using namespace musik::server;
|
||||
using namespace win32cpp;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ConnectedUsersListModel::ConnectedUsersListModel(ConnectedUsersListController *controller)
|
||||
: controller(controller)
|
||||
{
|
||||
musik::core::ServerPtr server = this->controller->connectedUsersController->server;
|
||||
if(server){
|
||||
server->UserSessionsUpdated.connect(this,&ConnectedUsersListModel::OnUsersUpdated);
|
||||
}
|
||||
this->UpdateUsers();
|
||||
|
||||
}
|
||||
|
||||
|
||||
uistring ConnectedUsersListModel::CellValueToString(int rowIndex, ListView::ColumnRef column){
|
||||
if(rowIndex<this->users.size() && rowIndex>=0){
|
||||
if(column==this->controller->ipColumn){
|
||||
return musik::core::ConvertUTF16(this->users[rowIndex]->IP());
|
||||
}
|
||||
return this->users[rowIndex]->user->Name();
|
||||
}
|
||||
|
||||
return uistring();
|
||||
}
|
||||
|
||||
void ConnectedUsersListModel::UpdateUsers(){
|
||||
musik::core::ServerPtr server = this->controller->connectedUsersController->server;
|
||||
if(server){
|
||||
this->users = server->ConnectedUserSessions();
|
||||
}
|
||||
|
||||
this->SetRowCount(0);
|
||||
this->SetRowCount((int)this->users.size());
|
||||
|
||||
}
|
||||
|
||||
void ConnectedUsersListModel::OnUsersUpdated(){
|
||||
if(!win32cpp::ApplicationThread::InMainThread()){
|
||||
win32cpp::ApplicationThread::Call0(this,&ConnectedUsersListModel::OnUsersUpdated);
|
||||
return;
|
||||
}
|
||||
|
||||
this->UpdateUsers();
|
||||
|
||||
}
|
||||
|
72
src/server/ConnectedUsersListModel.hpp
Normal file
72
src/server/ConnectedUsersListModel.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License Agreement:
|
||||
//
|
||||
// The following are Copyright © 2007, mC2 Team
|
||||
//
|
||||
// Sources and Binaries of: mC2
|
||||
//
|
||||
// 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 <server/ConnectedUsersListController.hpp>
|
||||
#include <win32cpp/ListView.hpp>
|
||||
#include <core/server/UserSession.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace musik { namespace server {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class ConnectedUsersListModel : public win32cpp::ListView::Model, public win32cpp::EventHandler{
|
||||
public:
|
||||
ConnectedUsersListModel(ConnectedUsersListController *controller);
|
||||
virtual win32cpp::uistring CellValueToString(int rowIndex, win32cpp::ListView::ColumnRef column);
|
||||
void UpdateUsers();
|
||||
private:
|
||||
|
||||
void OnUsersUpdated();
|
||||
|
||||
ConnectedUsersListController *controller;
|
||||
|
||||
friend class ConnectedUsersListController;
|
||||
|
||||
musik::core::server::UserSessionVector users;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} } // musik::server
|
@ -66,15 +66,12 @@ using namespace win32cpp;
|
||||
:mainWindow(mainWindow)
|
||||
,server(server)
|
||||
,mainFrame(NULL)
|
||||
,timer(200)
|
||||
,statusLabel(NULL)
|
||||
,syncpathController(NULL)
|
||||
,usersController(NULL)
|
||||
{
|
||||
|
||||
this->mainWindow.Created.connect(
|
||||
this, &MainWindowController::OnMainWindowCreated);
|
||||
|
||||
this->mainWindow.Handle()
|
||||
? this->OnMainWindowCreated(&this->mainWindow)
|
||||
: this->mainWindow.Created.connect(this, &MainWindowController::OnMainWindowCreated);
|
||||
}
|
||||
|
||||
MainWindowController::~MainWindowController()
|
||||
@ -85,33 +82,11 @@ MainWindowController::~MainWindowController()
|
||||
|
||||
void MainWindowController::OnMainWindowCreated(Window* window)
|
||||
{
|
||||
|
||||
// Start by setting the icon
|
||||
HICON icon16 = (HICON)LoadImage(Application::Instance(), MAKEINTRESOURCE(IDI_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
|
||||
HICON icon32 = (HICON)LoadImage(Application::Instance(), MAKEINTRESOURCE(IDI_MAINFRAME), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
|
||||
SendMessage( window->Handle(), WM_SETICON, WPARAM( ICON_SMALL ), LPARAM( icon16 ) );
|
||||
SendMessage( window->Handle(), WM_SETICON, WPARAM( ICON_BIG ), LPARAM( icon32 ) );
|
||||
|
||||
|
||||
// Init Tray Icon
|
||||
MenuRef myMenu = Menu::CreatePopup();
|
||||
|
||||
// Create Tray Menu
|
||||
MenuItemRef trayExit = myMenu->Items().Append(MenuItem::Create(_T("E&xit")));
|
||||
|
||||
// Bind Exit to handler
|
||||
trayExit->Activated.connect(this, &MainWindowController::OnFileExit);
|
||||
|
||||
UINT uidTrayIcon = Application::Instance().SysTrayManager()->AddIcon(Application::Instance().MainWindow(), icon16);
|
||||
Application::Instance().SysTrayManager()->SetTooltip(uidTrayIcon, _T("musikServer"));
|
||||
Application::Instance().SysTrayManager()->SetPopupMenu(uidTrayIcon, myMenu);
|
||||
Application::Instance().SysTrayManager()->EnableMinimizeToTray(uidTrayIcon);
|
||||
|
||||
|
||||
RedrawLock redrawLock(window);
|
||||
|
||||
{
|
||||
// Set window size and position
|
||||
musik::core::Preferences windowPrefs("ServerWindow");
|
||||
musik::core::Preferences windowPrefs("ServerSettingsWindow");
|
||||
this->mainWindow.MoveTo(windowPrefs.GetInt("x",200), windowPrefs.GetInt("y",200));
|
||||
this->mainWindow.Resize(windowPrefs.GetInt("width",500), windowPrefs.GetInt("height",400));
|
||||
this->mainWindow.SetMinimumSize(Size(320, 240));
|
||||
@ -123,22 +98,10 @@ void MainWindowController::OnMainWindowCreated(Window* window)
|
||||
|
||||
|
||||
// Create the layout
|
||||
this->mainFrame = new win32cpp::Frame(NULL,win32cpp::FramePadding(10));
|
||||
win32cpp::LinearLayout *mainRowLayout = new win32cpp::LinearLayout(win32cpp::LinearRowLayout);
|
||||
mainRowLayout->SetSpacing(10);
|
||||
mainRowLayout->SetDefaultChildFill(false);
|
||||
|
||||
// First a "Status" of the server
|
||||
win32cpp::LinearLayout *statusColumnLayout = mainRowLayout->AddChild( new win32cpp::LinearLayout(win32cpp::LinearColumnLayout) );
|
||||
win32cpp::Label *statusHeader = new win32cpp::Label(_T("Server status "));
|
||||
statusHeader->SetFont(boldFont);
|
||||
statusColumnLayout->AddChild( statusHeader );
|
||||
this->statusLabel = statusColumnLayout->AddChild( new win32cpp::Label(_T("")));
|
||||
this->mainFrame = new win32cpp::Frame(NULL,win32cpp::FramePadding(4));
|
||||
|
||||
// Second a TabView for the settings
|
||||
win32cpp::TabView *tabs = mainRowLayout->AddChild( new win32cpp::TabView() );
|
||||
mainRowLayout->SetChildFill(tabs,true);
|
||||
mainRowLayout->SetFlexibleChild(tabs);
|
||||
win32cpp::TabView *tabs = this->mainFrame->AddChild( new win32cpp::TabView() );
|
||||
|
||||
// Syncpath tab
|
||||
SyncpathView *synpathView = tabs->AddTab(uistring(_T("Sync paths")), new SyncpathView());
|
||||
@ -151,28 +114,18 @@ void MainWindowController::OnMainWindowCreated(Window* window)
|
||||
// Settings tab
|
||||
Frame *settingsView = tabs->AddTab(uistring(_T("Settings")), new Frame());
|
||||
|
||||
|
||||
this->mainFrame->AddChild(mainRowLayout);
|
||||
this->mainWindow.AddChild(mainFrame);
|
||||
|
||||
// Connect size and position signals
|
||||
this->mainWindow.Resized.connect(this, &MainWindowController::OnResize);
|
||||
this->mainWindow.Destroyed.connect(this, &MainWindowController::OnDestroyed);
|
||||
|
||||
// Start the status timer
|
||||
this->timer.OnTimeout.connect(this,&MainWindowController::UpdateStatus);
|
||||
this->timer.ConnectToWindow(&this->mainWindow);
|
||||
this->timer.Start();
|
||||
|
||||
|
||||
|
||||
this->mainWindow.Show(SW_MINIMIZE);
|
||||
this->mainWindow.Show(SW_HIDE);
|
||||
}
|
||||
|
||||
void MainWindowController::OnResize(Window* window, Size size)
|
||||
{
|
||||
RedrawLock redrawLock(this->mainFrame);
|
||||
RedrawLock redrawLock(window);
|
||||
this->mainFrame->Resize(this->mainWindow.ClientSize());
|
||||
}
|
||||
|
||||
@ -180,20 +133,10 @@ void MainWindowController::OnDestroyed(Window* window)
|
||||
{
|
||||
Point location( window->Location() );
|
||||
Size size( window->WindowSize() );
|
||||
musik::core::Preferences windowPrefs("ServerWindow");
|
||||
musik::core::Preferences windowPrefs("ServerSettingsWindow");
|
||||
windowPrefs.SetInt("x",location.x);
|
||||
windowPrefs.SetInt("y",location.y);
|
||||
windowPrefs.SetInt("width",size.width);
|
||||
windowPrefs.SetInt("height",size.height);
|
||||
}
|
||||
|
||||
void MainWindowController::UpdateStatus(){
|
||||
if(this->statusLabel && this->server){
|
||||
this->statusLabel->SetCaption( this->server->indexer.GetStatus() );
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindowController::OnFileExit(MenuItemRef menuItem)
|
||||
{
|
||||
Application::Instance().Terminate();
|
||||
}
|
||||
|
@ -73,19 +73,13 @@ class MainWindowController : public EventHandler
|
||||
void OnMainWindowCreated(Window* window);
|
||||
void OnResize(Window* window, Size size);
|
||||
void OnDestroyed(Window* window);
|
||||
void UpdateStatus();
|
||||
void OnFileExit(MenuItemRef menuItem);
|
||||
|
||||
protected:
|
||||
TopLevelWindow& mainWindow;
|
||||
musik::core::ServerPtr server;
|
||||
win32cpp::Label *statusLabel;
|
||||
win32cpp::Frame *mainFrame;
|
||||
SyncpathController *syncpathController;
|
||||
users::UsersController *usersController;
|
||||
|
||||
win32cpp::Timer timer;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <win32cpp/TopLevelWindow.hpp>
|
||||
#include <core/config.h>
|
||||
#include <core/Server.h>
|
||||
#include <server/ConnectedUsersController.hpp>
|
||||
#include <server/MainWindowController.hpp>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -59,7 +60,7 @@ int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPTSTR commandLi
|
||||
|
||||
// Create the main window and its controller
|
||||
TopLevelWindow mainWindow(_T("musikServer"));
|
||||
MainWindowController mainController(mainWindow,server);
|
||||
ConnectedUsersController mainController(mainWindow,server);
|
||||
|
||||
// Initialize and show the main window, and run the event loop.
|
||||
Application::Instance().Run(mainWindow);
|
||||
|
@ -295,6 +295,34 @@
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Connected users"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\ConnectedUsersController.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConnectedUsersController.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConnectedUsersListController.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConnectedUsersListController.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConnectedUsersListModel.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConnectedUsersListModel.hpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\main.cpp"
|
||||
|
@ -211,3 +211,8 @@ Window* TabView::WindowForTabIndex(int tabIndex)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Window* TabView::ActiveWindow()
|
||||
{
|
||||
return this->WindowForTabIndex(TabCtrl_GetCurSel(this->Handle()));
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ public: // methods
|
||||
|
||||
template <typename WindowType>
|
||||
WindowType* RemoveTab(WindowType* window);
|
||||
Window* ActiveWindow();
|
||||
|
||||
protected: // methods
|
||||
virtual HWND Create(Window* parent);
|
||||
|
Loading…
x
Reference in New Issue
Block a user