diff --git a/articles/3. Adding a button to the toolbar.md b/articles/3. Adding a button to the toolbar.md new file mode 100644 index 0000000..50d4117 --- /dev/null +++ b/articles/3. Adding a button to the toolbar.md @@ -0,0 +1,224 @@ +# Falkon Python Tutorial - 3. Adding a button to the toolbar + +In this chapter will be shown how to add Simple button to the toolbar. +The button has to be added to every window. +The button has to be added to new windows and removed when the window is closing. + +## Fill metadata +It feels like a paperwork but it has to be done. + +*metadata.desktop* + +``` +[Desktop Entry] +Name=Falkon Python Tutorial 3 +Comment=Adding a button to the toolbar +Icon= +Type=Service +X-Falkon-Type=Extension/Python + +X-Falkon-Author=Juraj Oravec +X-Falkon-Email=sgd.orava@gmail.com +X-Falkon-Version=1.0.0 +X-Falkon-Settings=false +``` + + +## Create button + +*TutorialButton.py* + +```python +import Falkon + + +class TutorialButton(Falkon.AbstractButtonInterface): + def __init__(self): + super().__init__() + + self.number = 0 + + self.setTitle("Tutorial 3") + self.setToolTip("Increment the number") + self.setBadgeText(str()) + + self.clicked.connect(self.onClicked) + + def id(self): + return "falkon-python-tutorial-3-button" + + def name(self): + return "Falkon Python Tutorial 3 Button" + + def onClicked(self, controller): + self.number += 1 + self.setBadgeText(str(self.number)) + +``` + +The button class has to inherit from `Falkon.AbstractButtonInterface`[1] + +### Falkon.AbstractButtonInterface +The interface class for Falkon buttons. + +#### id() +This id will be used by Falkon when you add the button to toolbar to determinate its place in the toolbar. + +#### name() +The name which will be displayed in "Configure toolbar" dialog. + +#### setTitle() +I did not find a sensible use for this function in the Falkons code yet. + +#### setToolTip() +The buttons tooltip which will be displayed when you hover with mouse over the button. + +#### setBadgeText() +The text in a form of a badge over the button. +Used by **AdBlock** plugin to show how many item it blocked. + +**Note:** When I set the badgeText in \__init__() it did not show in UI. +Maybe bug, maybe intentional behaviour, ask the Falkon author. + +#### clicked event +Emitted when the mouse click on the button. +In this example this signal is connected to `onClicked()` method + +#### onClicked() +The variable number is increased and its value is shown in the button badge. + + +## Plugin module + +*\__init__.py* + +```python +import Falkon +from PySide2 import QtCore +from Tutorial3.TutorialButton import TutorialButton + + +class Tutorial3_Plugin(Falkon.PluginInterface, QtCore.QObject): + def init(self, state, settingsPath): + self.buttons = {} + + plugins = Falkon.MainApplication.instance().plugins() + + plugins.mainWindowCreated.connect(self.mainWindowCreated) + plugins.mainWindowDeleted.connect(self.mainWindowDeleted) + + if state == Falkon.PluginInterface.LateInitState: + for window in Falkon.MainApplication.instance().windows(): + self.mainWindowCreated(window) + + def unload(self): + for window in Falkon.MainApplication.instance().windows(): + self.mainWindowDeleted(window) + + def testPlugin(self): + return True + + def mainWindowCreated(self, window): + b = TutorialButton() + window.navigationBar().addToolButton(b) + self.buttons[window] = b + + def mainWindowDeleted(self, window): + if window not in self.buttons: + return + + b = self.buttons[window] + window.navigationBar().removeToolButton(b) + del self.buttons[window] + + +Falkon.registerPlugin(Tutorial3_Plugin()) +``` + +To add a button to the Falkon interface we need to create new button for each window and store it somewhere. + +To add button to each window we create `mainWindowCreated()` and `mainWindowDeleted()` methods. + +```python + def mainWindowCreated(self, window): + b = TutorialButton() # Create an instance of the button + window.navigationBar().addToolButton(b) # Add button to toolbar + self.buttons[window] = b # store the button + + def mainWindowDeleted(self, window): + if window not in self.buttons: # Check if the button exist for selected window + return + + b = self.buttons[window] + window.navigationBar().removeToolButton(b) # remove the button from toolbar + del self.buttons[window] +``` + +When the methods are ready we connect them to `mainWindowCreated` and `mainWindowDeleted` event. + +```python + plugins = Falkon.MainApplication.instance().plugins() + + plugins.mainWindowCreated.connect(self.mainWindowCreated) + plugins.mainWindowDeleted.connect(self.mainWindowDeleted) +``` + +Variable `plugins` is an instance of [PluginProxy](https://github.com/KDE/falkon/blob/master/src/lib/plugins/pluginproxy.h). + +In case the extension is enabled when Falkon is already running we need to manually call `mainWindowCreated` method for each window. + +```python + if state == Falkon.PluginInterface.LateInitState: + for window in Falkon.MainApplication.instance().windows(): # Get list of currently open windows + self.mainWindowCreated(window) +``` + + +## Add button to statusbar +At the moment of writing this tutorial Falkon does not have any kind of configuration dialog to arrange buttons. +Buttons in statusbar are shown on 'first come first served' basis. + +To add button to statusbar only two lines are needed. + +### Update mainWindowCreated() + +The line which needs to be added: + +```python + window.statusBar().addButton(b) +``` + +### Update mainWindowDeleted() + +The line which needs to be added: + +```python + window.statusBar().removeButton(b) +``` + +### The result + +```python + def mainWindowCreated(self, window): + b = TutorialButton() + window.navigationBar().addToolButton(b) + window.statusBar().addButton(b) # For statusbar + self.buttons[window] = b + + def mainWindowDeleted(self, window): + if window not in self.buttons: + return + + b = self.buttons[window] + window.navigationBar().removeToolButton(b) + window.statusBar().removeButton(b) # For statusbar + del self.buttons[window] +``` + +It is simple, right ? + + + + + +[1]: https://github.com/KDE/falkon/blob/master/src/lib/tools/abstractbuttoninterface.h \ No newline at end of file diff --git a/extensions/Tutorial3/TutorialButton.py b/extensions/Tutorial3/TutorialButton.py new file mode 100644 index 0000000..763b343 --- /dev/null +++ b/extensions/Tutorial3/TutorialButton.py @@ -0,0 +1,44 @@ +""" +# ============================================================ +# Falkon Python Tutorial 3 - plugin for Falkon +# Copyright (C) 2019 Juraj Oravec +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# ============================================================ +""" + +import Falkon + + +class TutorialButton(Falkon.AbstractButtonInterface): + def __init__(self): + super().__init__() + + self.number = 0 + + self.setTitle("Tutorial 3") + self.setToolTip("Increment the number") + self.setBadgeText(str()) + + self.clicked.connect(self.onClicked) + + def id(self): + return "falkon-python-tutorial-3-button" + + def name(self): + return "Falkon Python Tutorial 3 Button" + + def onClicked(self, controller): + self.number += 1 + self.setBadgeText(str(self.number)) diff --git a/extensions/Tutorial3/__init__.py b/extensions/Tutorial3/__init__.py new file mode 100644 index 0000000..e55a3b1 --- /dev/null +++ b/extensions/Tutorial3/__init__.py @@ -0,0 +1,60 @@ +""" +# ============================================================ +# Falkon Python Tutorial 3 - plugin for Falkon +# Copyright (C) 2019 Juraj Oravec +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# ============================================================ +""" + +import Falkon +from PySide2 import QtCore +from Tutorial3.TutorialButton import TutorialButton + + +class Tutorial3_Plugin(Falkon.PluginInterface, QtCore.QObject): + def init(self, state, settingsPath): + self.buttons = {} + + plugins = Falkon.MainApplication.instance().plugins() + + plugins.mainWindowCreated.connect(self.mainWindowCreated) + plugins.mainWindowDeleted.connect(self.mainWindowDeleted) + + if state == Falkon.PluginInterface.LateInitState: + for window in Falkon.MainApplication.instance().windows(): + self.mainWindowCreated(window) + + def unload(self): + for window in Falkon.MainApplication.instance().windows(): + self.mainWindowDeleted(window) + + def testPlugin(self): + return True + + def mainWindowCreated(self, window): + b = TutorialButton() + window.navigationBar().addToolButton(b) + self.buttons[window] = b + + def mainWindowDeleted(self, window): + if window not in self.buttons: + return + + b = self.buttons[window] + window.navigationBar().removeToolButton(b) + del self.buttons[window] + + +Falkon.registerPlugin(Tutorial3_Plugin()) diff --git a/extensions/Tutorial3/metadata.desktop b/extensions/Tutorial3/metadata.desktop new file mode 100644 index 0000000..ba71a0a --- /dev/null +++ b/extensions/Tutorial3/metadata.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Falkon Python Tutorial 3 +Comment=Adding a button to the toolbar +Icon= +Type=Service +X-Falkon-Type=Extension/Python + +X-Falkon-Author=Juraj Oravec +X-Falkon-Email=sgd.orava@gmail.com +X-Falkon-Version=1.0.0 +X-Falkon-Settings=false