Hallo everybody, Since I am still realy new to Qt, plasma and KDE, I made a small draft of how I would imagine handling implemeting state machines in the PMC code. Please feel very free on adding and commenting ideas, and pointing out stupid things. Marco and Aaron were already so nice to give me a small nudge in the hopefully right direction.
Thanks all, Chris (aka binarylooks) ___________________________ 1) the top level libs (mediacenter.h) class knows about which types of applets (=UIComponents) exist and which states exist Example: enum State { BrowseVideos; PlayVideos; PlayMusic; MusicVisualizations; BrowsePictures; SinglePictures; PicturesSlideshow; } enum UIComponent { ControlBar; InfoBar; Browser; Player; Playlist; HomeScreen; } _________________________________ 2) there is a MediaCenterState class which keeps track of all possible smallwidgets (=subComponents) for the whole PMC and can hand out pointers to them. (Maybe the state objects can do that for the widgets that are needed in their state) Example: enum subComponent { iconVideoMode; iconMusciMode; iconPictureMode; iconHomeScreen; iconTogglePlaylistAutohide; iconToggleControlBarAutohide; iconToggleInfoBarAutohide; iconVideoModePlayPause; iconVideoModeSkipForward; iconVideoModeSkipBackward; iconVideoModeStop; iconMusicModePlayPause; iconMusicModeSkipForward; iconMusicModeSkipBackward; iconMusicModeStop; sliderMusicModeVolume; sliderMusicModeSeek; iconSlideshow; iconRotateCW; iconRotateCCW; ... } class MEDIACENTER_EXPORT MediaCenterState(QObject *parent) : QAbstractState(parent) m_iconVideosMode(new Plasma::IconWidget(this)) //initialize all of them { } //here we handle the pointers of the created objects (the enum, initialilzation and pointer handling could be in the actual subclass of the state objects QGraphicsWidget *BrowseVideoState::giveComponent(MediaCenter::subComponent component) { if (component == iconVideoMode) { m_videoModeWidget->setIcon("bla"); return m_videoModeWidget; } } _________________________________ 3) there will be subclasses (like BrowseVideoState) of the above class that can handle each mode _________________________________ 4) The MediaContainment starts the state machine Example: //Prepare StateMachine QStateMachine machine; //this is not a pointer //Set up all possible states MediaCenterState mediaCenterState = new MediaCenterState(); //these are pointers VideoBrowserState videoBrowserState = new VideoBrowserState(mediaCenterState); .... //Define state change buttons mediaCenterState->addTransition(m_control, SIGNAL(switchToVideoBrowseState()), videoBrowseState); mediaCenterState->addTransition(m_control, SIGNAL(switchToPicturesBrowseState()), pictureBrowseState); //Define other signals for state change mediaCenterState->addTransition(player, SIGNAL(slideshowStopped()), pictureBrowseState); //Setup and start statemachine machine.addState(mediaCenterState); //this is our toplevel state mediaCenterState->setInitialState(videoBrowserState); //set this to the homescreen state eventually machine.start(); _________________________________ 5) these sublasses will be used by the MediaContainment to create state objects The mediacontainment initiates state switches while handing pointers of the UIComponents to the state objects Example: QList<MediaCenter::UIComponent> uiComponentsList; //pointer will be added in the setApplet functions _________________________________ 6) the state objects (i.e. BrowseVideoState) use the pointers of the UIComponents to tell them to add subComponents to them They also configure the UIComponents. This all happens on state change (enter and exit methods) The pointers of the subComponents are either created in each state class, or they are created and handed out by another class (maybe MediaCenterState). Example of functions to be reimplemented: assignPoperty(Object, "property", "value") invokeMethodOnEntry(this, "method") Example of code: void BrowseVideoState::invokeOnEntry(QList<MediaCenter::UIComponents> list) { For each UIComponent in list { if (UIComponent == "ControlBar") { subComponentsList.clear(); subComponentsList << addSubComponent(MediaCenterState::giveComponent(MediaCenter::iconVideoMode)); subComponentsList << addSubComponent(MediaCenterState::giveComponent(MediaCenter::iconPictureMode)); ...//add all widgets configure UIComponent (show, hide, autohide,...) } if UIComponent = "InfolBar" { ...//add widgets } ...//treat all UIComponents } } void BrowseVideoState::exit() { For each UIComponent in list { if (UIComponent == "ControlBar") { UIComponent->removeSubComponents(subComponentsList); } } } _________________________________ 7) The type definitions of the UIComponents in the libs (playbackcontrol.h, browser.h,...) predefine the necessary functions for adding and removing subComponents which need to be reimplemented by the actual UIComponents themselves The type definitions also need to show which public slots and signals need to be available by the actual applets. Important are the switchState slots. that each UIComponent needs to have. Example: //This class defines what an actual implementation of a controlbar needs to be able to do //When adding a subComponent we need to return it. This is necessary to keep a track of them in a list in the state object MediaCenter::subComponent addSubComponent(MediaCenter::SubComponent) { } //This class gets the exact pointers of who do remove in a list void removeSubComponents(MediaCenter::SubComponent(QList<MediaCenter::SubComponents>) { } _________________________________ 8) The actual UIComponents (mediacontroller.h, mediabrowser.h,...) need to reimplement how to layout subComponents to themsleves and how to remove them from their layouts.They will get the pointers to the subComponents during state change by the state objects. (see point 6) Example: MediaCenter::subComponent addSubComponent(MediaCenter::SubComponent) { create layout add subComponent show subComponent } void removeSubComponents(QList<MediaCenter::SubComponents>) { for each subComponent hide subcomponent remove them from layout } _______________________________________________ Plasma-devel mailing list Plasma-devel@kde.org https://mail.kde.org/mailman/listinfo/plasma-devel