bool ShortcutChooser::onShortcutKeyPress(GdkEventKey* ev) { std::string statusText(""); /** greebo: Workaround for allowing Shift+TAB as well (Tab becomes ISO_Left_Tab in that case) */ if (ev->keyval == GDK_ISO_Left_Tab) { ev->keyval = GDK_Tab; } // Store the shortcut string representation into the Entry field _entry->set_text(GlobalEventManager().getGDKEventStr(ev)); // Store this key/modifier combination for later use (UPPERCASE!) _keyval = gdk_keyval_to_upper(ev->keyval); _state = ev->state; IEventPtr foundEvent = GlobalEventManager().findEvent(ev); // Only display the note if any event was found and it's not the "self" event if (!foundEvent->empty() && foundEvent != _event) { statusText = (boost::format(_("Note: This is already assigned to: <b>%s</b>")) % GlobalEventManager().getEventName(foundEvent)).str(); } _statusWidget->set_markup(statusText); return true; // don't propagate }
// Loads the default shortcuts from the registry void EventManager::loadAccelerators() { if (_debugMode) { std::cout << "EventManager: Loading accelerators...\n"; } xml::NodeList shortcutSets = GlobalRegistry().findXPath("user/ui/input//shortcuts"); if (_debugMode) { std::cout << "Found " << shortcutSets.size() << " sets.\n"; } // If we have two sets of shortcuts, delete the default ones if (shortcutSets.size() > 1) { GlobalRegistry().deleteXPath("user/ui/input//shortcuts[@name='default']"); } // Find all accelerators xml::NodeList shortcutList = GlobalRegistry().findXPath("user/ui/input/shortcuts//shortcut"); if (shortcutList.size() > 0) { rMessage() << "EventManager: Shortcuts found in Registry: " << static_cast<int>(shortcutList.size()) << std::endl; for (unsigned int i = 0; i < shortcutList.size(); i++) { const std::string key = shortcutList[i].getAttributeValue("key"); if (_debugMode) { std::cout << "Looking up command: " << shortcutList[i].getAttributeValue("command") << "\n"; std::cout << "Key is: >> " << key << " << \n"; } // Try to lookup the command IEventPtr event = findEvent(shortcutList[i].getAttributeValue("command")); // Check for a non-empty key string if (key != "") { // Check for valid command definitions were found if (!event->empty()) { // Get the modifier string (e.g. "SHIFT+ALT") const std::string modifierStr = shortcutList[i].getAttributeValue("modifiers"); if (!duplicateAccelerator(key, modifierStr, event)) { // Create the accelerator object IAccelerator& accelerator = addAccelerator(key, modifierStr); // Connect the newly created accelerator to the command accelerator.connectEvent(event); } } else { rWarning() << "EventManager: Cannot load shortcut definition (command invalid)." << std::endl; } } } } else { // No accelerator definitions found! rWarning() << "EventManager: No shortcut definitions found..." << std::endl; } }
bool EventManager::QueueEvent(const IEventPtr& pEvent) { CB_ASSERT(m_ActiveQueue >= 0); CB_ASSERT(m_ActiveQueue < EVENTMANAGER_NUM_QUEUES); if (!pEvent) { CB_ERROR("Invalid Event"); return false; } CB_LOG("Events", "Attempting to queue event: " + std::string(pEvent->GetName())); // make sure there are listeners for this event auto findIt = m_EventListeners.find(pEvent->GetEventType()); if (findIt != m_EventListeners.end()) { m_Queues[m_ActiveQueue].push_back(pEvent); CB_LOG("Events", "Successfully queued event: " + std::string(pEvent->GetName())); return true; } else { CB_LOG("Events", "No listeners for event: " + std::string(pEvent->GetName())); return false; } }
void TestPubSub() { IEventPtr events = IEventPtr(new TEvent()); IIOCPEventedPtr iocp_evented = IIOCPEventedPtr(new TIOCPEvented(events)); for(;;) { events->WaitOne(); iocp_evented->completion_port().Flush(); } }
void TestEcho() { IEventPtr events = IEventPtr(new TEvent()); IIOCPEventedPtr iocp_evented = IIOCPEventedPtr(new TIOCPEvented(events)); TEchoTest echo_test(iocp_evented, "127.0.0.1", 333, 128); for(;;) { events->WaitOne(); iocp_evented->completion_port().Flush(); } }
/* Checks the passed xmlNode for a recognized item (ToolButton, ToggleToolButton, Separator) * Returns the widget or NULL if nothing useful is found */ GtkWidget* ToolbarManager::createToolItem(xml::Node& node) { const std::string nodeName = node.getName(); GtkWidget* toolItem; if (nodeName == "separator") { toolItem = GTK_WIDGET(gtk_separator_tool_item_new()); } else if (nodeName == "toolbutton" || nodeName == "toggletoolbutton") { // Found a button, load the values that are shared by both types const std::string name = node.getAttributeValue("name"); const std::string icon = node.getAttributeValue("icon"); const std::string tooltip = _(node.getAttributeValue("tooltip").c_str()); const std::string action = node.getAttributeValue("action"); if (nodeName == "toolbutton") { // Create a new GtkToolButton and assign the right callback toolItem = GTK_WIDGET(gtk_tool_button_new(NULL, name.c_str())); } else { // Create a new GtkToggleToolButton and assign the right callback toolItem = GTK_WIDGET(gtk_toggle_tool_button_new()); } IEventPtr event = GlobalEventManager().findEvent(action); if (!event->empty()) { event->connectWidget(GTK_WIDGET(toolItem)); // Tell the event to update the state of this button event->updateWidgets(); } else { globalErrorStream() << "ToolbarManager: Failed to lookup command " << action << std::endl; } // Set the tooltip, if not empty if (tooltip != "") { gtk_tool_item_set_tooltip(GTK_TOOL_ITEM(toolItem), _tooltips, tooltip.c_str(), ""); } // Load and assign the icon, if specified if (icon != "") { GtkWidget* image = gtk_image_new_from_pixbuf(GlobalUIManager().getLocalPixbufWithMask(icon)); gtk_widget_show(image); gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(toolItem), image); } } else { return NULL; } gtk_widget_show(toolItem); return toolItem; }
// Connects the given accelerator to the given command (identified by the string) void EventManager::connectAccelerator(IAccelerator& accelerator, const std::string& command) { IEventPtr event = findEvent(command); if (!event->empty()) { // Command found, connect it to the accelerator by passing its pointer accelerator.connectEvent(event); } else { // Command NOT found rWarning() << "EventManager: Unable to connect command: " << command << std::endl; } }
// Checks if the eventName is already registered and writes to rMessage, if so bool EventManager::alreadyRegistered(const std::string& eventName) { // Try to find the command and see if it's already registered IEventPtr foundEvent = findEvent(eventName); if (foundEvent->empty()) { return false; } else { rWarning() << "EventManager: Event " << eventName << " already registered!" << std::endl; return true; } }
void EventManager::disconnectAccelerator(const std::string& command) { IEventPtr event = findEvent(command); if (!event->empty()) { // Cycle through the accelerators and check for matches for (AcceleratorList::iterator i = _accelerators.begin(); i != _accelerators.end(); i++) { if (i->match(event)) { // Connect the accelerator to the empty event (disable the accelerator) i->connectEvent(_emptyEvent); i->setKey(0); i->setModifiers(0); } } } else { // Command NOT found rWarning() << "EventManager: Unable to disconnect command: " << command << std::endl; } }
bool EventManager::TriggerEvent(const IEventPtr& pEvent) const { CB_LOG("Events", "Attempting to trigger event " + std::string(pEvent->GetName())); bool processed = false; // iterate the map looking for this event type auto findIt = m_EventListeners.find(pEvent->GetEventType()); if (findIt != m_EventListeners.end()) { // iterate the listener list and send the event to each listener const EventListenerList& listeners = findIt->second; for (EventListenerList::const_iterator it = listeners.begin(); it != listeners.end(); ++it) { EventListenerDelegate listener = (*it); CB_LOG("Events", "Sending event " + std::string(pEvent->GetName()) + " to delegate listener."); listener(pEvent); processed = true; } } return processed; }
ParticlePreview::ParticlePreview() { // Add one additional toolbar for particle-related stuff Gtk::Toolbar* toolbar = Gtk::manage(new Gtk::Toolbar); toolbar->set_toolbar_style(Gtk::TOOLBAR_ICONS); _showAxesButton = Gtk::manage(new Gtk::ToggleToolButton); _showAxesButton->signal_toggled().connect( sigc::mem_fun(this, &ParticlePreview::queue_draw) ); _showAxesButton->set_icon_widget(*Gtk::manage(new Gtk::Image( GlobalUIManager().getLocalPixbufWithMask("axes.png")))); _showAxesButton->set_tooltip_text(_("Show coordinate axes")); Gtk::ToolButton* reloadButton = Gtk::manage(new Gtk::ToolButton); reloadButton->set_icon_widget(*Gtk::manage(new Gtk::Image(Gtk::Stock::REFRESH, Gtk::ICON_SIZE_MENU))); reloadButton->set_tooltip_text(_("Reload Particle Defs")); IEventPtr ev = GlobalEventManager().findEvent("ReloadParticles"); ev->connectWidget(reloadButton); _showWireFrameButton = Gtk::manage(new Gtk::ToggleToolButton); _showWireFrameButton->set_icon_widget(*Gtk::manage(new Gtk::Image( GlobalUIManager().getLocalPixbufWithMask("wireframe.png")))); _showWireFrameButton->set_tooltip_text(_("Show wireframe")); _showWireFrameButton->signal_toggled().connect( sigc::mem_fun(this, &ParticlePreview::queue_draw) ); _automaticLoopButton = Gtk::manage(new Gtk::ToggleToolButton(_("Auto Loop"))); _automaticLoopButton->set_tooltip_text(_("Auto Loop")); toolbar->insert(*_showAxesButton, 0); toolbar->insert(*_showWireFrameButton, 0); toolbar->insert(*_automaticLoopButton, 0); toolbar->insert(*reloadButton, 0); addToolbar(*toolbar); }
// Push event into active queue bool EventManager::VQueueEvent( const IEventPtr& pEvent ) { ENG_ASSERT( m_ActiveQueue >= 0 ); ENG_ASSERT( m_ActiveQueue < EVENTMANAGER_NUM_QUEUES ); auto mapIt = m_EventListeners.find( pEvent->VGetEventType() ); // If no one is listening, abort if( mapIt == m_EventListeners.end() || !mapIt->second.size() ) { return false; } m_EventQueues[m_ActiveQueue].push_back( pEvent ); return true; }
// Make all listeners process the event right now instead of add the event into queue bool EventManager::VTriggerEvent( IEventPtr pEvent ) const { auto mapIt = m_EventListeners.find( pEvent->VGetEventType() ); // corresponding listing list is not exist if( mapIt == m_EventListeners.end() ) { return false; } auto eventListenerList = mapIt->second; bool processed = false; for( auto listIt = eventListenerList.begin(); listIt != eventListenerList.end(); ++listIt ) { EventListenerDelegate listener = (*listIt); // trigger event listener( pEvent ); processed = true; } return processed; }
bool EventManager::VUpdate( unsigned long maxMs ) { unsigned long currMs = (unsigned long) ( GetGlobalTimer()->GetTime() * 1000.0 ); unsigned long targetMs = ( maxMs == kINFINITE )? kINFINITE: currMs + maxMs; // swap active queues and clear the new queue after the swap int queueToProcess = m_ActiveQueue; m_ActiveQueue = (m_ActiveQueue + 1) % EVENTMANAGER_NUM_QUEUES; m_EventQueues[m_ActiveQueue].clear(); std::string s( ( "EventLoop", "Processing Event Queue " + ToStr( queueToProcess ) + "; " + ToStr( ( unsigned long ) m_EventQueues[ queueToProcess ].size() ) + " events to process" ) ); \ Logger::Log( "EventLoop", s, NULL, NULL, 0 ); \ /*ENG_LOG("EventLoop", "Processing Event Queue " + ToStr(queueToProcess) + "; " + ToStr((unsigned long)m_EventQueues[queueToProcess].size()) + " events to process");*/ // Process the queue while ( !m_EventQueues[queueToProcess].empty() ) { // pop the front of the queue IEventPtr pEvent = m_EventQueues[queueToProcess].front(); m_EventQueues[queueToProcess].pop_front(); ENG_LOG( "EventLoop", "\t\tProcessing Event " + std::string( pEvent->GetName() ) ); const EventType& eventType = pEvent->VGetEventType(); // find all the delegate functions registered for this event auto findIt = m_EventListeners.find(eventType); if (findIt != m_EventListeners.end()) { const EventListenerList& eventListeners = findIt->second; ENG_LOG("EventLoop", "\t\tFound " + ToStr((unsigned long)eventListeners.size()) + " delegates"); // call each listener for (auto it = eventListeners.begin(); it != eventListeners.end(); ++it) { EventListenerDelegate listener = (*it); ENG_LOG("EventLoop", "\t\tSending event " + std::string(pEvent->GetName()) + " to delegate"); listener(pEvent); } } // check to see if time ran out currMs = (unsigned long) ( GetGlobalTimer()->GetTime() * 1000.0 ); if ( targetMs != IEventManager::kINFINITE && currMs >= targetMs ) { ENG_LOG("EventLoop", "Aborting event processing; time ran out"); break; } } // If we couldn't process all of the events, push the remaining events to the new active queue. // Note: To preserve sequencing, go back-to-front, inserting them at the head of the active queue bool queueFlushed = ( m_EventQueues[queueToProcess].empty() ); if ( !queueFlushed ) { while (!m_EventQueues[queueToProcess].empty()) { IEventPtr pEvent = m_EventQueues[queueToProcess].back(); m_EventQueues[queueToProcess].pop_back(); m_EventQueues[m_ActiveQueue].push_front(pEvent); } } return queueFlushed; }
bool ShortcutChooser::assignShortcut() { bool shortcutsChanged = false; // Check, if the user has pressed a meaningful key if (_keyval != 0) { // Construct an eventkey structure to be passed to the EventManager query GdkEventKey eventKey; eventKey.keyval = _keyval; eventKey.state = _state; // Try to lookup an existing command with the same shortcut IEventPtr foundEvent = GlobalEventManager().findEvent(&eventKey); // Only react on non-empty and non-"self" events if (!foundEvent->empty() && foundEvent != _event) { // There is already a command connected to this shortcut, ask the user const std::string foundEventName = GlobalEventManager().getEventName(foundEvent); // Construct the message std::string message = (boost::format(_("The specified shortcut is already assigned to <b>%s</b>" "\nOverwrite the current setting and assign this shortcut to <b>%s</b> instead?")) % foundEventName % _commandName).str(); // Fire up the dialog to ask the user what action to take IDialogPtr popup = GlobalDialogManager().createMessageBox( _("Overwrite existing shortcut?"), message, ui::IDialog::MESSAGE_ASK); // Only react on "YES" if (popup->run() == ui::IDialog::RESULT_YES) { // Disconnect both the found command and the new command GlobalEventManager().disconnectAccelerator(foundEventName); GlobalEventManager().disconnectAccelerator(_commandName); // Create a new accelerator and connect it to the selected command IAccelerator& accel = GlobalEventManager().addAccelerator(&eventKey); GlobalEventManager().connectAccelerator(accel, _commandName); shortcutsChanged = true; } } else { // No command is using the accelerator up to now, so assign it // Disconnect the current command to avoid duplicate accelerators GlobalEventManager().disconnectAccelerator(_commandName); // Create a new accelerator and connect it to the selected command IAccelerator& accel = GlobalEventManager().addAccelerator(&eventKey); GlobalEventManager().connectAccelerator(accel, _commandName); shortcutsChanged = true; } } else { // No key is specified, disconnect the command GlobalEventManager().disconnectAccelerator(_commandName); shortcutsChanged = true; } return shortcutsChanged; }
bool EventManager::Update(unsigned long maxMillis) { unsigned long currMS = GetTickCount(); // set the max milliseconds to process events unsigned long maxMS = (maxMillis == IEventManager::kINFINITE) ? IEventManager::kINFINITE : currMS + maxMillis; // handle events from other threads IEventPtr pRealtimeEvent; while (m_RealTimeEventQueue.try_pop(pRealtimeEvent)) { QueueEvent(pRealtimeEvent); currMS = GetTickCount(); if (maxMillis != IEventManager::kINFINITE) { if (currMS >= maxMS) { CB_ERROR("Too many real time processes hitting the event manager"); } } } // swap active queues and clear the new active after the swap int queueToProcess = m_ActiveQueue; m_ActiveQueue = (m_ActiveQueue + 1) % EVENTMANAGER_NUM_QUEUES; m_Queues[m_ActiveQueue].clear(); CB_LOG("EventLoop", "Processing Event Queue " + ToStr(queueToProcess) + "; " + ToStr((unsigned long)m_Queues[queueToProcess].size()) + " events to process"); // process the queue of events while (!m_Queues[queueToProcess].empty()) { // process the first event and pop it IEventPtr pEvent = m_Queues[queueToProcess].front(); m_Queues[queueToProcess].pop_front(); CB_LOG("EventLoop", "\t\tProcessing Event " + std::string(pEvent->GetName())); const EventType& eventType = pEvent->GetEventType(); // find all the listeners registered for this event in the map auto findIt = m_EventListeners.find(eventType); if (findIt != m_EventListeners.end()) { // get the list of listeners const EventListenerList& listeners = findIt->second; CB_LOG("Event Loop", "\t\tFound " + ToStr((unsigned long)listeners.size()) + " listeners"); // call each listener for this event type for (auto it = listeners.begin(); it != listeners.end(); ++it) { EventListenerDelegate listener = *it; CB_LOG("EventLoop", "\t\tSending event " + std::string(pEvent->GetName()) + " to listener"); listener(pEvent); } } // check to see if time ran out currMS = GetTickCount(); if (maxMillis != IEventManager::kINFINITE && currMS >= maxMS) { CB_LOG("EventLoop", "Aborting event processing, time ran out"); break; } } bool queueFlushed = m_Queues[queueToProcess].empty(); // if we couldn't process all events, push remaining events on the new active queue if (!queueFlushed) { while (!m_Queues[queueToProcess].empty()) { IEventPtr pEvent = m_Queues[queueToProcess].back(); m_Queues[queueToProcess].pop_back(); m_Queues[m_ActiveQueue].push_front(pEvent); } } return queueFlushed; }