diff --git a/CMakeLists.txt b/CMakeLists.txt index fee4070..ab6be95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,18 @@ -cmake_minimum_required(VERSION 3.0.0) -cmake_policy(SET CMP0048 NEW) -project(UTLauncher VERSION 0.3.6) +if(WITH_APPINDICATOR) + cmake_minimum_required(VERSION 2.8.12) + project(UTLauncher) +else() + cmake_minimum_required(VERSION 3.0.0) + cmake_policy(SET CMP0048 NEW) + project(UTLauncher VERSION 0.3.6) +endif() set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules") include(MingwResource) include(Version) -include(DeployQt5) # For Mac +if(APPLE) + include(DeployQt5) # For Mac +endif() # Find includes in corresponding build directories set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -18,6 +25,30 @@ find_package(PkgConfig) find_package(ZLIB) #find_package(Boost COMPONENTS system REQUIRED) +# Ubuntu Appindicator GTK2-------------------------------------------- +if(WITH_APPINDICATOR) + pkg_check_modules(PC_APPINDICATOR REQUIRED appindicator-0.1) + pkg_check_modules(GTK2 REQUIRED gtk+-2.0) + + find_path(APPINDICATOR_INCLUDE_DIR NAMES libappindicator/app-indicator.h + HINTS ${PC_APPINDICATOR_INCLUDEDIR} ${PC_APPINDICATOR_INCLUDE_DIRS} + PATH_SUFFIXES libappindicator-0.1) + + find_library(APPINDICATOR_LIBRARY NAMES appindicator) + + include(FindPackageHandleStandardArgs) + + find_package_handle_standard_args(APPINDICATOR DEFAULT_MSG APPINDICATOR_LIBRARY APPINDICATOR_INCLUDE_DIR) + + if(APPINDICATOR_FOUND) + set(APPINDICATOR_LIBRARIES ${APPINDICATOR_LIBRARY}) + set(APPINDICATOR_INCLUDE_DIRS ${APPINDICATOR_INCLUDE_DIR}) + endif() + + mark_as_advanced(APPINDICATOR_INCLUDE_DIR APPINDICATOR_LIBRARY) +endif() +# ------------------------------------------------------------ + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") #pkg_check_modules(LIBTORRENT libtorrent-rasterbar) @@ -25,16 +56,21 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBTORRENT_CFLAGS_STR}") if(CMAKE_BUILD_TYPE MATCHES Release) -add_definitions(-DQT_NO_DEBUG_OUTPUT) + add_definitions(-DQT_NO_DEBUG_OUTPUT) endif() add_subdirectory(3rdparty) -include_directories(${3rdparty_INCLUDE_DIRS}) +if(APPINDICATOR_FOUND) + include_directories(${3rdparty_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${APPINDICATOR_INCLUDE_DIR}) + link_directories(${GTK2_LIBRARY_DIRS} ${APPINDICATOR_LIBRARY}) +else() + include_directories(${3rdparty_INCLUDE_DIRS}) +endif() qt5_add_resources(resources files.qrc flags.qrc) if(CMAKE_SYSTEM_NAME MATCHES Windows) -add_win32_resource(rc_srcs application.rc) + add_win32_resource(rc_srcs application.rc) endif(CMAKE_SYSTEM_NAME MATCHES Windows) add_definitions(-DLAUNCH_WITH_UE4) @@ -50,8 +86,13 @@ else() set(BUILD_TYPE "") endif() -set(UTLauncher_VERSION "${PROJECT_VERSION}" CACHE STRING "Version number" FORCE INTERNAL) -set_version_number(UTLauncher) +if(APPINDICATOR_FOUND) + set(UTLauncher_VERSION "0.3.6" CACHE STRING "Version number" FORCE INTERNAL) + set_version_number(UTLauncher) +else() + set(UTLauncher_VERSION "${PROJECT_VERSION}" CACHE STRING "Version number" FORCE INTERNAL) + set_version_number(UTLauncher) +endif() add_definitions(-DNO_DOWNLOAD -DVERSION_MAJOR=${UTLauncher_VERSION_MAJOR} -DVERSION_MINOR=${UTLauncher_VERSION_MINOR} -DVERSION_PATCH=${UTLauncher_VERSION_PATCH}) add_executable(UTLauncher ${BUILD_TYPE} ${resources} ${rc_srcs} main.cpp utlauncher.cpp download.cpp utsplash.cpp bootstrap.cpp serverbrowser.cpp configdialog.cpp $ $) @@ -61,7 +102,12 @@ if(STATIC_BUILD_WIN32) add_definitions(-DSTATIC_PLUGIN_WINDOWS) target_link_libraries(UTLauncher Qt5::Widgets Qt5::QWindowsIntegrationPlugin Qt5::Network ${QT5WIDGETS_LDFLAGS} ${ZLIB_LIBRARY}) else() - target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + if(APPINDICATOR_FOUND) + add_definitions(-DAPPINDICATOR) + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY} ${GTK2_LIBRARIES} ${APPINDICATOR_LIBRARY}) + else() + target_link_libraries(UTLauncher Qt5::Widgets Qt5::Network ${Boost_SYSTEM_LIBRARY} ${ZLIB_LIBRARY}) + endif() endif() install(TARGETS UTLauncher BUNDLE DESTINATION . RUNTIME DESTINATION bin) diff --git a/README.md b/README.md index 42d1393..478533c 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,12 @@ pacman -U utlauncher-git*.pkg.tar.xz ### Build instructions #### Requirements -You need to install Qt5 base development package, G++ compiler and cmake. +You need to install Qt5 base development package, libappindicator-dev, G++ compiler and cmake. ##### Ubuntu ``` -sudo apt-add-repository ppa:ubuntu-sdk-team/ppa -sudo apt-get update -sudo apt-get install qtbase5-dev g++ cmake +sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev +Important: Build will fail without "-DWITH_APPINDICATOR=1" ``` ##### openSUSE `sudo zypper install libqt5-qtbase-devel gcc-c++ cmake` @@ -45,7 +44,17 @@ cd UTLauncher git submodule update --init --recursive cd build cmake .. -DCMAKE_BUILD_TYPE=Release +``` +to build with ubuntu appindicator: +``` +cmake .. -DCMAKE_BUILD_TYPE=Release -DWITH_APPINDICATOR=1 +``` + +``` make +``` +optional: +``` sudo make install ``` diff --git a/appindicator.h b/appindicator.h new file mode 100644 index 0000000..56b944f --- /dev/null +++ b/appindicator.h @@ -0,0 +1,143 @@ +#ifndef APPINDICATOR_H +#define APPINDICATOR_H + +#undef signals +extern "C" { + + #include + #include + + void serverlistIndicator(GtkMenu *, gpointer); + void runutIndicator(GtkMenu *, gpointer); + void runeditorIndicator(GtkMenu *, gpointer); + void quitIndicator(GtkMenu *, gpointer); +} +#define signals public +/* +void UTLauncher::startServerBrowser() + systemTrayMenu->addAction(showBrowser); + systemTrayMenu->addSeparator(); + systemTrayMenu->addAction(runUTAction); + systemTrayMenu->addAction(runEditorAction); + systemTrayMenu->addSeparator(); + systemTrayMenu->addAction(quitAction); +*/ + + +void serverlistIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //UTLauncher *self = static_cast(data); + + //self->startServerBrowser().showBrowser.exec(); + //showBrowser +} + +void runutIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //runUTAction +} + +void runeditorIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + //runEditorAction +} + +void quitIndicator(GtkMenu *menu, gpointer data) { + Q_UNUSED(menu); + QApplication *self = static_cast(data); + + self->quit(); +} + +void ShowUnityAppIndicator() +{ + AppIndicator *indicator; + GtkWidget *menu, *quit_item, *serverlist_item, *runut_item, *runeditor_item; + + menu = gtk_menu_new(); + + serverlist_item = gtk_menu_item_new_with_label("Server List"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), serverlist_item); + g_signal_connect(serverlist_item, "activate", + G_CALLBACK(serverlistIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(serverlist_item); + + runut_item = gtk_menu_item_new_with_label("Run UT"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), runut_item); + g_signal_connect(runut_item, "activate", + G_CALLBACK(runutIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(runut_item); + + runeditor_item = gtk_menu_item_new_with_label("Run Editor"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), runeditor_item); + g_signal_connect(runeditor_item, "activate", + G_CALLBACK(runeditorIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(runeditor_item); + + quit_item = gtk_menu_item_new_with_label("Quit"); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), quit_item); + g_signal_connect(quit_item, "activate", + G_CALLBACK(quitIndicator), qApp); // We cannot connect + // gtk signal and qt slot so we need to create proxy + // function later on, we pass qApp pointer as an argument. + // This is useful when we need to call signals on "this" + //object so external function can access current object + gtk_widget_show(quit_item); + + +/* +auto showBrowser = new QAction(awesome->icon(fa::listalt), "Server List", this); + connect(showBrowser, &QAction::triggered, [=]() { + browser->showNormal(); + browser->raise(); + browser->activateWindow(); + }); + + auto runUTAction = new QAction(awesome->icon( fa::gamepad ),"Run UT", this); + connect(runUTAction, &QAction::triggered, [=]() { + QString exePath = bootstrap.programExePath(); + if(!exePath.length()) { + browser->show(); + openSettings(); + return; + } + QProcess::startDetached(exePath); + }); + + auto runEditorAction = new QAction(awesome->icon( fa::code ),"Run Editor", this); + connect(runEditorAction, &QAction::triggered, [=]() { + QString editorPath = bootstrap.editorExePath(); + QString projectPath = bootstrap.projectPath(); + QProcess::startDetached(editorPath, QStringList() << projectPath); + }); +*/ + indicator = app_indicator_new( + "UTLauncher", //id + "indicator_utlauncher", //icon default:indicator-messages + APP_INDICATOR_CATEGORY_APPLICATION_STATUS //category + ); + + QFile tempfile; + tempfile.copy(":/indicator_utlauncher.png", QDir::tempPath()+"/indicator_utlauncher.png"); + // not working... + //tempfile.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ReadUser | QFile::WriteUser | QFile::ReadOther | QFile::WriteOther); + + app_indicator_set_icon_theme_path(indicator, "/tmp"); + app_indicator_set_icon_full(indicator, "indicator_utlauncher", ""); + + app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE); + app_indicator_set_menu(indicator, GTK_MENU(menu)); +} +#endif diff --git a/configdialog.h b/configdialog.h index 042d017..a6371aa 100644 --- a/configdialog.h +++ b/configdialog.h @@ -291,6 +291,8 @@ class ConfigDialog : public QDialog locationsButton->setSizeHint(QSize(80, 64)); buttonMap[locationsButton] = 0; + //only show when appindicator is disabled + #ifndef APPINDICATOR auto uiButton = new QListWidgetItem(contentsWidget); uiButton->setIcon(awesome->icon(fa::desktop)); uiButton->setText(tr("UI")); @@ -298,7 +300,7 @@ class ConfigDialog : public QDialog uiButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); uiButton->setSizeHint(QSize(80, 64)); buttonMap[uiButton] = 1; - + #endif connect(contentsWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), diff --git a/files.qrc b/files.qrc index ff9fec4..bb89979 100644 --- a/files.qrc +++ b/files.qrc @@ -2,5 +2,6 @@ splash.jpg icon.png + indicator_utlauncher.png \ No newline at end of file diff --git a/indicator_utlauncher.png b/indicator_utlauncher.png new file mode 100644 index 0000000..f1759e0 Binary files /dev/null and b/indicator_utlauncher.png differ diff --git a/serverbrowser.h b/serverbrowser.h index 0473e2a..4f33b3a 100644 --- a/serverbrowser.h +++ b/serverbrowser.h @@ -472,6 +472,12 @@ class ServerBrowser : public QMainWindow this->hide(); return; } + + //not working --> file is read only... + #ifdef APPINDICATOR + QFile::remove(QDir::tempPath()+"/indicator_utlauncher.png"); + #endif + QMainWindow::closeEvent(event); } diff --git a/ubuntu_dependencies b/ubuntu_dependencies new file mode 100644 index 0000000..4afe997 --- /dev/null +++ b/ubuntu_dependencies @@ -0,0 +1,3 @@ +sudo apt-get install qtbase5-dev g++ cmake libappindicator-dev +sudo apt-get remove qtbase5-dev g++ cmake libappindicator-dev + diff --git a/utlauncher.cpp b/utlauncher.cpp index b4b3d8e..dc5b655 100644 --- a/utlauncher.cpp +++ b/utlauncher.cpp @@ -7,6 +7,10 @@ #include "configdialog.h" #include +#ifdef APPINDICATOR +#include "appindicator.h" +#endif + QtAwesome* awesome; QColor UTLauncher::iconColor() const { @@ -323,6 +327,15 @@ void UTLauncher::startServerBrowser() systemTrayMenu->addAction(quitAction); systemTray.setContextMenu(systemTrayMenu); + + // shows unity appindicator + #ifdef APPINDICATOR + // hide qt systemtray - not working on unity + systemTray.hide(); + ShowUnityAppIndicator(); //TODO: implement full appindicator + #endif + + #ifndef APPINDICATOR systemTray.show(); connect(&systemTray, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason) { @@ -344,5 +357,5 @@ void UTLauncher::startServerBrowser() } }); - + #endif } \ No newline at end of file