WIP Merging basic player to master #6

Merged
blue merged 17 commits from player into master 2019-02-01 22:32:52 +00:00
14 changed files with 394 additions and 72 deletions
Showing only changes of commit 0e31c5fdf2 - Show all commits

View File

@ -43,7 +43,7 @@ Corax::Corax(QObject *parent):
attributes->addAttribute(W::String(u"connectionsCount"), new M::String(W::String(u"0"), W::Address({u"attributes", u"connectionCount"}))); attributes->addAttribute(W::String(u"connectionsCount"), new M::String(W::String(u"0"), W::Address({u"attributes", u"connectionCount"})));
attributes->addAttribute(W::String(u"name"), new M::String(W::String(u"Corax"), W::Address({u"attributes", u"name"}))); attributes->addAttribute(W::String(u"name"), new M::String(W::String(u"Corax"), W::Address({u"attributes", u"name"})));
attributes->addAttribute(W::String(u"version"), new M::String(W::String(u"0.0.2"), W::Address({u"attributes", u"version"}))); attributes->addAttribute(W::String(u"version"), new M::String(W::String(u"0.0.3"), W::Address({u"attributes", u"version"})));
attributes->addAttribute(W::String(u"players"), new M::String(W::String(u"0"), W::Address({u"attributes", u"players"}))); attributes->addAttribute(W::String(u"players"), new M::String(W::String(u"0"), W::Address({u"attributes", u"players"})));
createCaches(); createCaches();

View File

@ -4,27 +4,43 @@ M::Player::Player(const W::Address& address, QObject* parent):
M::Model(address, parent), M::Model(address, parent),
controls(), controls(),
views(), views(),
playPauseBtn(new M::Button(address + W::Address{u"Play"})), playPauseBtn(new M::Button(address + W::Address{u"play"})),
nextBtn(new M::Button(address + W::Address{u"next"})),
prevBtn(new M::Button(address + W::Address{u"prev"})),
_queueView(new M::List(address + W::Address{u"queueView"})), _queueView(new M::List(address + W::Address{u"queueView"})),
_queue(), _queue(),
current(0), current(0),
counter(0), counter(0),
currentIndex(0),
mode(playBack), mode(playBack),
playing(false) playing(false),
scheduledToplay(false)
{ {
W::Handler* get = W::Handler::create(address + W::Address({u"get"}), this, &M::Player::_h_get); W::Handler* get = W::Handler::create(address + W::Address({u"get"}), this, &M::Player::_h_get);
W::Handler* hqueue = W::Handler::create(address + W::Address({u"queue"}), this, &M::Player::_h_queue); W::Handler* hqueue = W::Handler::create(address + W::Address({u"queue"}), this, &M::Player::_h_queue);
addHandler(get); addHandler(get);
addHandler(hqueue); addHandler(hqueue);
playPauseBtn->setLabel(W::String(u"play")); playPauseBtn->setLabel(W::String(u"Play"));
playPauseBtn->setEnabled(false); playPauseBtn->setEnabled(false);
connect(playPauseBtn, SIGNAL(activated()), this, SLOT(onPlayPauseBtn())); connect(playPauseBtn, SIGNAL(activated()), this, SLOT(onPlayPauseBtn()));
nextBtn->setLabel(W::String(u"Next"));
nextBtn->setEnabled(false);
connect(nextBtn, SIGNAL(activated()), this, SLOT(onNextBtn()));
prevBtn->setLabel(W::String(u"Prev"));
prevBtn->setEnabled(false);
connect(prevBtn, SIGNAL(activated()), this, SLOT(onPrevBtn()));
addModel(playPauseBtn); addModel(playPauseBtn);
addModel(nextBtn);
addModel(prevBtn);
addModel(_queueView); addModel(_queueView);
controls.insert(std::make_pair(playPause, playPauseBtn->getAddress())); controls.insert(std::make_pair(playPause, playPauseBtn->getAddress()));
controls.insert(std::make_pair(next, nextBtn->getAddress()));
controls.insert(std::make_pair(prev, prevBtn->getAddress()));
views.insert(std::make_pair(queue, _queueView->getAddress())); views.insert(std::make_pair(queue, _queueView->getAddress()));
} }
@ -93,23 +109,9 @@ void M::Player::h_get(const W::Event& ev)
void M::Player::onPlayPauseBtn() void M::Player::onPlayPauseBtn()
{ {
if (playing) { if (playing) {
playPauseBtn->setLabel(W::String(u"Play")); pause();
playing = false;
switch (mode) {
case playBack:
broadcast(new W::Vocabulary(), W::Address{u"pause"});
break;
}
} else { } else {
playPauseBtn->setLabel(W::String(u"Pause")); play();
playing = true;
switch (mode) {
case playBack:
broadcast(new W::Vocabulary(), W::Address{u"play"});
break;
}
} }
} }
@ -120,24 +122,174 @@ void M::Player::h_queue(const W::Event& ev)
const W::Uint64& id = static_cast<const W::Uint64&>(data.at(u"id")); const W::Uint64& id = static_cast<const W::Uint64&>(data.at(u"id"));
ProxySong* song = new ProxySong(id, address + W::Address{W::String(W::Uint64(counter++).toString())}); ProxySong* song = new ProxySong(id, address + W::Address{W::String(W::Uint64(counter++).toString())});
addModel(song); addModel(song);
_queue.push_back(song);
_queueView->push(song->getAddress());
if (current == 0) { if (current == 0) {
scheduledToplay = true;
setActive(song);
}
if (currentIndex + 1 < _queue.size()) {
nextBtn->setEnabled(true);
}
}
void M::Player::play()
{
if (!playing) {
playPauseBtn->setLabel(W::String(u"Pause"));
playing = true;
switch (mode) {
case playBack:
if (current == 0) {
scheduledToplay = true;
} else {
if (current->isReady()) {
scheduledToplay = false;
broadcast(new W::Vocabulary(), W::Address{u"play"});
break;
} else {
scheduledToplay = true;
}
}
}
}
}
void M::Player::pause()
{
if (playing) {
playPauseBtn->setLabel(W::String(u"Play"));
playing = false;
switch (mode) {
case playBack:
scheduledToplay = false;
broadcast(new W::Vocabulary(), W::Address{u"pause"});
break;
}
}
}
void M::Player::onSongReady()
{
emit serviceMessage("Song is ready");
playPauseBtn->setEnabled(true);
if (scheduledToplay) {
scheduledToplay = false;
if (playing) {
scheduledToplay = false;
broadcast(new W::Vocabulary(), W::Address{u"play"});
} else {
play();
}
}
}
void M::Player::onSongNotReady()
{
playPauseBtn->setEnabled(false);
emit serviceMessage("Something happend to the current song, not sure yet what to do");
}
void M::Player::onNextBtn()
{
if (currentIndex + 1 < _queue.size()) {
if (playing) {
pause();
scheduledToplay = true;
}
setActive(currentIndex + 1);
}
}
void M::Player::onPrevBtn()
{
if (currentIndex > 0) {
if (playing) {
pause();
scheduledToplay = true;
}
setActive(currentIndex - 1);
}
}
void M::Player::setActive(ProxySong* song)
{
if (current == song) {
return;
}
bool found = false;
int index;
for (index = 0; index < _queue.size(); ++index) {
if (_queue.at(index) == song) {
found = true;
break;
}
}
if (found) {
setActive(index);
} else {
emit serviceMessage("An attempt to set active a song which is no in the queue, not supposed to happen");
return;
}
}
void M::Player::setActive(uint64_t index)
{
if (index >= _queue.size()) {
emit serviceMessage("An attempt to set active a song which is no in the queue, not supposed to happen");
return;
}
ProxySong* song = _queue.at(index);
currentIndex = index;
if (currentIndex + 1 < _queue.size()) {
nextBtn->setEnabled(true);
} else {
nextBtn->setEnabled(false);
}
if (currentIndex > 0) {
prevBtn->setEnabled(true);
} else {
prevBtn->setEnabled(false);
}
W::Vocabulary* res = new W::Vocabulary();
W::Vector* add = new W::Vector();
W::Vector* remove = new W::Vector();
if (current != 0) {
disconnect(current, SIGNAL(ready()), this, SLOT(onSongReady()));
disconnect(current, SIGNAL(notReady()), this, SLOT(onSongNotReady()));
remove->push(new W::Uint64(currentPlayback));
}
current = song; current = song;
connect(song, SIGNAL(ready()), this, SLOT(onSongReady()));
connect(song, SIGNAL(notReady()), this, SLOT(onSongNotReady()));
views.insert(std::make_pair(currentPlayback, song->getAddress())); views.insert(std::make_pair(currentPlayback, song->getAddress()));
W::Vocabulary* avc = new W::Vocabulary(); W::Vocabulary* avc = new W::Vocabulary();
avc->insert(u"type", new W::Uint64(currentPlayback)); avc->insert(u"type", new W::Uint64(currentPlayback));
avc->insert(u"address", song->getAddress()); avc->insert(u"address", song->getAddress());
W::Vector* add = new W::Vector();
add->push(avc); add->push(avc);
W::Vocabulary* res = new W::Vocabulary();
res->insert(u"add", add); res->insert(u"add", add);
res->insert(u"remove", new W::Vector()); res->insert(u"remove", remove);
broadcast(res, W::Address{u"viewsChange"}); broadcast(res, W::Address{u"viewsChange"});
if (song->isReady()) {
playPauseBtn->setEnabled(true); playPauseBtn->setEnabled(true);
if (scheduledToplay) {
play();
}
} else { } else {
_queue.push_back(song); playPauseBtn->setEnabled(false);
_queueView->push(song->getAddress());
} }
} }

View File

@ -32,13 +32,18 @@ namespace M {
playPause, playPause,
currentPlayback, currentPlayback,
queue, queue,
picture picture,
prev,
next
}; };
enum Mode { enum Mode {
playBack playBack
}; };
void play();
void pause();
protected: protected:
void h_subscribe(const W::Event & ev) override; void h_subscribe(const W::Event & ev) override;
@ -52,15 +57,26 @@ namespace M {
ItemMap controls; ItemMap controls;
ItemMap views; ItemMap views;
M::Button* playPauseBtn; M::Button* playPauseBtn;
M::Button* nextBtn;
M::Button* prevBtn;
M::List* _queueView; M::List* _queueView;
Queue _queue; Queue _queue;
ProxySong* current; ProxySong* current;
uint64_t counter; uint64_t counter;
uint64_t currentIndex;
Mode mode; Mode mode;
bool playing; bool playing;
bool scheduledToplay;
void setActive(ProxySong* song);
void setActive(uint64_t index);
private slots: private slots:
void onPlayPauseBtn(); void onPlayPauseBtn();
void onNextBtn();
void onPrevBtn();
void onSongReady();
void onSongNotReady();
}; };
} }

View File

@ -175,6 +175,8 @@ void Database::clear()
lmdb::txn transaction = lmdb::txn::begin(environment); lmdb::txn transaction = lmdb::txn::begin(environment);
dbi.drop(transaction); dbi.drop(transaction);
transaction.commit(); transaction.commit();
elements.clear();
} }
void Database::addModel(M::Model* model) void Database::addModel(M::Model* model)

View File

@ -44,6 +44,15 @@ void M::ICatalogue::clear()
broadcast(new W::Vocabulary(), W::Address{u"clear"}); broadcast(new W::Vocabulary(), W::Address{u"clear"});
} }
std::map<uint64_t, M::Vocabulary*>::iterator aItr = activeChildren.begin();
std::map<uint64_t, M::Vocabulary*>::iterator aEnd = activeChildren.end();
for (; aItr != aEnd; ++aItr) {
removeModel(aItr->second);
aItr->second->deleteLater();
}
activeChildren.clear();
emit countChange(0); emit countChange(0);
} }

View File

@ -188,7 +188,7 @@ var Controller = Subscribable.inherit({
} }
if (this._registered) { if (this._registered) {
global.registerForeignController(pair.n, pair.c); global.unregisterForeignController(pair.n, pair.c);
} }
pair.c.off("serviceMessage", this._onControllerServiceMessage, this); pair.c.off("serviceMessage", this._onControllerServiceMessage, this);

View File

@ -34,7 +34,6 @@ var Audio = File.inherit({
this._waitingForFrames = false; this._waitingForFrames = false;
} }
this.initialized = true;
return ac; return ac;
}, },
_h_responseFrames: function(ev) { _h_responseFrames: function(ev) {

View File

@ -63,6 +63,11 @@ var File = Controller.inherit({
if (ac) { if (ac) {
this.trigger("additionalChange"); this.trigger("additionalChange");
} }
if (!this.initialized) {
this.initialized = true;
this.trigger("ready");
}
}, },
"needData": function() { "needData": function() {
if (this._need === 0) { if (this._need === 0) {

View File

@ -30,7 +30,7 @@ var LocalModel = Subscribable.inherit({
for (i = 0; i < this._foreignControllers.length; ++i) { for (i = 0; i < this._foreignControllers.length; ++i) {
var pair = this._foreignControllers[i]; var pair = this._foreignControllers[i];
global.unsubscribeForeignController(pair.n, pair.c); global.unsubscribeForeignController(pair.n, pair.c);
global.registerForeignController(pair.n, pair.c); global.unregisterForeignController(pair.n, pair.c);
pair.c.destructor(); pair.c.destructor();
} }

View File

@ -27,11 +27,8 @@ var Player = Controller.inherit({
this.views = Object.create(null); this.views = Object.create(null);
this.mode = PlayerMode.straight.playback; this.mode = PlayerMode.straight.playback;
this._audio = null; this._audio = null;
this._source = new Source();
this._asset = new AV.Asset(this._source);
this._player = new AV.Player(this._asset);
this._player.play();
this._createStateMachine(); this._createStateMachine();
this._createPlayingInfrastructure();
this.addHandler("get"); this.addHandler("get");
this.addHandler("viewsChange"); this.addHandler("viewsChange");
@ -54,6 +51,8 @@ var Player = Controller.inherit({
if (ItemType.reversed[t] !== undefined) { if (ItemType.reversed[t] !== undefined) {
switch (t) { switch (t) {
case ItemType.straight.playPause: case ItemType.straight.playPause:
case ItemType.straight.prev:
case ItemType.straight.next:
var btn = new Button(address.clone()); var btn = new Button(address.clone());
btn.itemType = t; btn.itemType = t;
this.controls[t] = btn; this.controls[t] = btn;
@ -61,10 +60,10 @@ var Player = Controller.inherit({
this.trigger("newElement", btn, t); this.trigger("newElement", btn, t);
break; break;
default: default:
this.trigger("serviceMessage", "An attempt to add ItemType " + ItemType.reversed[t] + " to controls of the Player, but it's not qualified to be a control"); this.trigger("serviceMessage", "An attempt to add ItemType " + ItemType.reversed[t] + " to controls of the Player, but it's not qualified to be a control", 1);
} }
} else { } else {
this.trigger("serviceMessage", "An unrecgnized item ItemType in Player: " + t); this.trigger("serviceMessage", "An unrecgnized item ItemType in Player: " + t, 1);
} }
}, },
_addView: function(type, address) { _addView: function(type, address) {
@ -79,7 +78,7 @@ var Player = Controller.inherit({
if (ItemType.reversed[t] !== undefined) { if (ItemType.reversed[t] !== undefined) {
switch (t) { switch (t) {
case ItemType.straight.queue: case ItemType.straight.queue:
this.trigger("serviceMessage", "Queue is not supported yet in Player"); this.trigger("serviceMessage", "Queue is not supported yet in Player", 1);
break; break;
case ItemType.straight.currentPlayback: case ItemType.straight.currentPlayback:
ctrl = new Vocabulary(address.clone()); ctrl = new Vocabulary(address.clone());
@ -96,10 +95,10 @@ var Player = Controller.inherit({
supported = false; //just to avoid adding with addController, since ImageById is not a controller supported = false; //just to avoid adding with addController, since ImageById is not a controller
break; break;
default: default:
this.trigger("serviceMessage", "An attempt to add ItemType " + ItemType.reversed[t] + " to views of the Player, but it's not qualified to be a view"); this.trigger("serviceMessage", "An attempt to add ItemType " + ItemType.reversed[t] + " to views of the Player, but it's not qualified to be a view", 1);
} }
} else { } else {
this.trigger("serviceMessage", "An unrecgnized item ItemType in Player: " + t); this.trigger("serviceMessage", "An unrecognized item ItemType in Player: " + t, 1);
} }
if (supported) { if (supported) {
@ -110,6 +109,16 @@ var Player = Controller.inherit({
this.trigger("newElement", ctrl, t); this.trigger("newElement", ctrl, t);
} }
}, },
_createPlayingInfrastructure() {
if (this._source) {
this._source.reset();
this._asset.stop();
this._player.stop();
}
this._source = new Source();
this._asset = new AV.Asset(this._source);
this._player = new AV.Player(this._asset);
},
_createStateMachine: function() { _createStateMachine: function() {
this._fsm = new StateMachine("initial", graphs[this.mode]); this._fsm = new StateMachine("initial", graphs[this.mode]);
this._fsm.on("stateChanged", this._onStateChanged, this); this._fsm.on("stateChanged", this._onStateChanged, this);
@ -159,7 +168,7 @@ var Player = Controller.inherit({
size = remove.length(); size = remove.length();
for (i = 0; i < size; ++i) { for (i = 0; i < size; ++i) {
this._removeView(remove.at(i)); this._removeView(remove.at(i).valueOf());
} }
size = add.length(); size = add.length();
@ -179,6 +188,9 @@ var Player = Controller.inherit({
this._fsm.manipulation("noMoreFrames"); this._fsm.manipulation("noMoreFrames");
} }
}, },
_onControllerReady: function() {
this._fsm.manipulation("controllerReady");
},
_onNewPlayBackElement: function(key, element) { _onNewPlayBackElement: function(key, element) {
switch (key) { switch (key) {
case "image": case "image":
@ -191,6 +203,7 @@ var Player = Controller.inherit({
this._audio = new Audio(new Address(["music", element.toString()])); this._audio = new Audio(new Address(["music", element.toString()]));
this.addForeignController("Corax", this._audio); this.addForeignController("Corax", this._audio);
this._audio.on("newFrames", this._onAudioNewFrames, this); this._audio.on("newFrames", this._onAudioNewFrames, this);
this._audio.on("ready", this._onControllerReady, this);
this._fsm.manipulation("controller"); this._fsm.manipulation("controller");
} }
break; break;
@ -199,7 +212,7 @@ var Player = Controller.inherit({
_onNewRemoveBackElement: function(key) { _onNewRemoveBackElement: function(key) {
switch (key) { switch (key) {
case "image": case "image":
this._removeView(new Uint64(ItemType.straight.picture)); this._removeView(ItemType.straight.picture);
break; break;
case "audio": case "audio":
this.removeForeignController(this._audio); this.removeForeignController(this._audio);
@ -210,14 +223,35 @@ var Player = Controller.inherit({
_onStateChanged: function(e) { _onStateChanged: function(e) {
switch (e.newState) { switch (e.newState) {
case "initial": case "initial":
if (e.manipulation === "noController") {
this.removeForeignController(this._audio);
this._audio.destructor();
this._audio = null;
this._createPlayingInfrastructure();
}
break; break;
case "initialPlaying": case "initialPlaying":
if (e.manipulation === "noController") {
this._player.pause();
this.removeForeignController(this._audio);
this.audio.destructor();
this._audio = null;
this._createPlayingInfrastructure();
}
break; break;
case "controllerNotReady":
break
case "controllerNotReadyPlaying":
break
case "hasController": case "hasController":
break; break;
case "hasControllerPlaying": case "hasControllerPlaying":
if (this._audio.hasMore()) { if (this._audio.hasMore()) {
this._audio.requestMore(); this._audio.requestMore();
this._player.play(); //todo temporal
} else { } else {
this._fsm.manipulation("noMoreFrames"); this._fsm.manipulation("noMoreFrames");
} }
@ -249,10 +283,30 @@ var Player = Controller.inherit({
} }
}, },
_removeControl: function(type) { _removeControl: function(type) {
//TODO var ctrl = this.controls[type];
if (ctrl !== undefined) {
this.trigger("removeElement", type);
this.removeController(ctrl);
ctrl.destructor();
}
}, },
_removeView: function(type) { _removeView: function(type) {
//TODO var view = this.views[type];
if (view !== undefined) {
this.trigger("removeElement", type);
if (type !== ItemType.straight.picture) {
this.removeController(view);
}
if (type === ItemType.straight.currentPlayback) {
if (this.views[ItemType.straight.picture]) {
this._removeView(ItemType.straight.picture);
}
this._fsm.manipulation("noController");
}
delete this.views[type];
view.destructor();
}
} }
}); });
@ -261,6 +315,8 @@ ItemType.add("playPause");
ItemType.add("currentPlayback"); ItemType.add("currentPlayback");
ItemType.add("queue"); ItemType.add("queue");
ItemType.add("picture"); ItemType.add("picture");
ItemType.add("prev");
ItemType.add("next");
var PlayerMode = new Enum("PlayerMode"); var PlayerMode = new Enum("PlayerMode");
PlayerMode.add("playback"); PlayerMode.add("playback");
@ -270,34 +326,48 @@ Player.ItemType = ItemType;
var graphs = Object.create(null); var graphs = Object.create(null);
graphs[PlayerMode.straight.playback] = { graphs[PlayerMode.straight.playback] = {
"initial": { "initial": {
controller: "hasController", controller: "controllerNotReady",
play: "initialPlaying" play: "initialPlaying"
}, },
"initialPlaying": { "initialPlaying": {
pause: "initial", pause: "initial",
controller: "hasControllerPlaying" controller: "controllerNotReadyPlaying"
},
"controllerNotReady": {
play: "controllerNotReadyPlaying",
controllerReady: "hasController"
},
"controllerNotReadyPlaying": {
pause: "controllerNotReady",
controllerReady: "hasControllerPlaying"
}, },
"hasController": { "hasController": {
newFrames: "paused", newFrames: "paused",
play: "hasControllerPlaying" play: "hasControllerPlaying",
noController: "initial"
}, },
"hasControllerPlaying": { "hasControllerPlaying": {
newFrames: "playing", newFrames: "playing",
pause: "hasController" pause: "hasController",
noController: "initialPlaying"
}, },
"paused": { "paused": {
play: "playing", play: "playing",
noController: "initial",
noMoreFrames: "pausedAllLoaded" noMoreFrames: "pausedAllLoaded"
}, },
"pausedAllLoaded": { "pausedAllLoaded": {
play: "playingAllLoaded" play: "playingAllLoaded",
noController: "initial"
}, },
"playing": { "playing": {
pause: "paused", pause: "paused",
noMoreFrames: "playingAllLoaded" noMoreFrames: "playingAllLoaded",
noController: "initialPlaying"
}, },
"playingAllLoaded": { "playingAllLoaded": {
pause: "pausedAllLoaded" pause: "pausedAllLoaded",
noController: "initialPlaying"
} }
} }

View File

@ -142,6 +142,9 @@
this._emptyHelper = new LocalModel(); this._emptyHelper = new LocalModel();
this._gc.on("serviceMessage", this._onServiceMessage, this);
this._ps.on("serviceMessage", this._onServiceMessage, this);
this._gc.on("themeSelected", this.setTheme, this); this._gc.on("themeSelected", this.setTheme, this);
this._ps.on("pageName", this._onPageName, this); this._ps.on("pageName", this._onPageName, this);
}, },
@ -175,6 +178,24 @@
address: this._currentPageCtl.getPairAddress().toArray() address: this._currentPageCtl.getPairAddress().toArray()
}, "", name); }, "", name);
}, },
"_onServiceMessage": function(text, severity) {
var fn;
switch (severity) {
case 2:
fn = console.error;
break;
case 1:
fn = console.warn;
break;
case 0:
default:
fn = console.info;
break;
}
fn(text);
},
"_onSocketConnected": function(name) { "_onSocketConnected": function(name) {
console.log(name + " socket connected"); console.log(name + " socket connected");
var node = this._nodes[name]; var node = this._nodes[name];
@ -301,6 +322,8 @@
this._playerCtl.register(this.dispatcher, this._nodes["Corax"].socket); this._playerCtl.register(this.dispatcher, this._nodes["Corax"].socket);
this._playerCtl.subscribe(); this._playerCtl.subscribe();
this._mainLayout.appendPlayer(this._playerCtl); this._mainLayout.appendPlayer(this._playerCtl);
this._playerCtl.on("serviceMessage", this._onServiceMessage, this);
}, },
"setTheme": function(theme) { "setTheme": function(theme) {
View.setTheme(theme); View.setTheme(theme);

View File

@ -47,5 +47,13 @@ div.dragging .draggable {
} }
.disabled { .disabled {
opacity: 0.7; opacity: 0.5;
}
.button {
cursor: pointer
}
.button.disabled {
cursor: not-allowed
} }

View File

@ -20,6 +20,7 @@
Layout.fn.constructor.call(this, controller, base); Layout.fn.constructor.call(this, controller, base);
this.addClass("hoverable"); this.addClass("hoverable");
this.addClass("button");
this._enabled = true; this._enabled = true;
this._hasLabel = false; this._hasLabel = false;
this._e.addEventListener("click", this._onClick.bind(this), false); this._e.addEventListener("click", this._onClick.bind(this), false);
@ -27,10 +28,8 @@
controller.on("setEnabled", this._onSetEnabled, this); controller.on("setEnabled", this._onSetEnabled, this);
controller.on("setLabel", this._onSetLabel, this); controller.on("setLabel", this._onSetLabel, this);
if (controller.initialized) {
this._onSetEnabled(controller.enabled); this._onSetEnabled(controller.enabled);
this._onSetLabel(controller.hasLabel, controller.label); this._onSetLabel(controller.hasLabel, controller.label);
}
}, },
"destructor": function() { "destructor": function() {
this._f.off("setEnabled", this._onSetEnabled, this); this._f.off("setEnabled", this._onSetEnabled, this);

View File

@ -30,6 +30,8 @@
GridLayout.fn.constructor.call(this, ctrl, options); GridLayout.fn.constructor.call(this, ctrl, options);
this._playPause = null; this._playPause = null;
this._prev = null;
this._next = null;
this._picture = null; this._picture = null;
this._cpbCtrl = null; this._cpbCtrl = null;
this._infoModels = { this._infoModels = {
@ -39,16 +41,17 @@
} }
ctrl.on("newElement", this._onNewElement, this); ctrl.on("newElement", this._onNewElement, this);
ctrl.on("removeElement", this._onRemoveElement, this);
var artist = new Label(this._infoModels.artist); var artist = new Label(this._infoModels.artist);
var album = new Label(this._infoModels.album); var album = new Label(this._infoModels.album);
var song = new Label(this._infoModels.song); var song = new Label(this._infoModels.song);
var spacer = new View(helper); var spacer = new View(helper);
this.append(artist, 0, 2, 1, 1, GridLayout.Aligment.LeftCenter); this.append(artist, 0, 4, 1, 1, GridLayout.Aligment.LeftCenter);
this.append(song, 1, 2, 1, 1, GridLayout.Aligment.LeftCenter); this.append(song, 1, 4, 1, 1, GridLayout.Aligment.LeftCenter);
this.append(album, 2, 2, 1, 1, GridLayout.Aligment.LeftCenter); this.append(album, 2, 4, 1, 1, GridLayout.Aligment.LeftCenter);
this.append(spacer, 0, 3, 3, 1, GridLayout.Aligment.LeftCenter); this.append(spacer, 0, 5, 3, 1, GridLayout.Aligment.LeftCenter);
this._uncyclic.push(this._infoModels.artist.destructor.bind(this._infoModels.artist)); this._uncyclic.push(this._infoModels.artist.destructor.bind(this._infoModels.artist));
this._uncyclic.push(this._infoModels.song.destructor.bind(this._infoModels.song)); this._uncyclic.push(this._infoModels.song.destructor.bind(this._infoModels.song));
@ -56,6 +59,7 @@
}, },
destructor: function() { destructor: function() {
this._f.off("newElement", this._onNewElement, this); this._f.off("newElement", this._onNewElement, this);
this._f.off("removeElement", this._onRemoveElement, this);
this._clearCpbCtrl(); this._clearCpbCtrl();
GridLayout.fn.destructor.call(this); GridLayout.fn.destructor.call(this);
@ -73,7 +77,15 @@
switch (type) { switch (type) {
case ItemType.straight.playPause: case ItemType.straight.playPause:
this._playPause = new Button(ctrl); this._playPause = new Button(ctrl);
this.append(this._playPause, 0, 1, 3, 1); this.append(this._playPause, 0, 2, 3, 1);
break;
case ItemType.straight.prev:
this._prev = new Button(ctrl);
this.append(this._prev, 0, 1, 3, 1);
break;
case ItemType.straight.next:
this._next = new Button(ctrl);
this.append(this._next, 0, 3, 3, 1);
break; break;
case ItemType.straight.queue: case ItemType.straight.queue:
break; break;
@ -92,6 +104,33 @@
break; break;
} }
}, },
_onRemoveElement: function(type) {
var ItemType = Enum.storage["ItemType"];
switch (type) {
case ItemType.straight.playPause:
this._playPause.destructor();
this._playPause = null;
break;
case ItemType.straight.prev:
this._prev.destructor();
this._prev = null;
break;
case ItemType.straight.next:
this._next.destructor();
this._next = null;
break;
case ItemType.straight.queue:
break;
case ItemType.straight.currentPlayback:
this._clearCpbCtrl();
break;
case ItemType.straight.picture:
this._picture.destructor();
this._picture = null;
break;
}
},
_onCpbNewElement: function(key, value) { _onCpbNewElement: function(key, value) {
var model = this._infoModels[key]; var model = this._infoModels[key];