Skip to content

Commit

Permalink
feat: -> 0.0.1: Initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
guillaume-florent committed Feb 6, 2023
1 parent 7e094b9 commit 2bee6b9
Show file tree
Hide file tree
Showing 15 changed files with 1,453 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/.idea

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
recursive-include freecad/the_experimental_workbench/resources *
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
# The_Experimental_WB
An experimental FreeCAD workbench for all kinds of tests and experiments

An experimental FreeCAD workbench for all kinds of tests and experiments.

Use the new/namespace structure for workbenches.

See: https://github.com/FreeCAD/freecad.workbench_starterkit
127 changes: 127 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Code Snippets
There is no way to add a button, menu entry from python to a workbench which is added with c++. So here is a comparison how to do that with python and with c++.

## Adding a command:
This can be done either with python or c++.

### 1. python

```python
import FreeCAD as App

class MyCommand(object):
def IsActive(self):
"""
availability of the command (eg.: check for existence of a document,...)
if this function returns False, the menu/ buttons are ßdisabled (gray)
"""
if App.ActiveDocument is None:
return False
else:
return True

def GetResources(self):
"""
resources which are used by buttons and menu-items
"""
return {'Pixmap': 'path_to_icon.svg', 'MenuText': 'my command', 'ToolTip': 'very short description'}

def Activated(self):
"""
the function to be handled, when a user starts the command
"""
```
To register the command in FreeCAD:

```python
import FreeCADGui as Gui
Gui.addCommand('MyCommand', MyCommand())
```

Adding a new toolbar/menu:
```python
from FreeCADGui import Workbench
class myWorkbench(Workbench):
MenuText = "name_of_workbench"
ToolTip = "short description of workbench"
Icon = "path_to_icon.svg"

def GetClassName(self):
return "Gui::PythonWorkbench"

def Initialize(self):
self.appendToolbar("Gear", ["MyCommand"])
self.appendMenu("Gear", ["MyCommand"])
```

### 2. C++

```c++

#include <App/Document.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Gui/Document.h>

using namespace std;

DEF_STD_CMD_A(MyCommand)

MyCommand::MyCommand()
: Command("MyCommand")
{
sAppModule = "module";
sGroup = QT_TR_NOOP("Mesh");
sMenuText = QT_TR_NOOP("my command");
sToolTipText = QT_TR_NOOP("very short description");
sWhatsThis = "MyCommand";
sStatusTip = sToolTipText;
}

void MyCommand::activated(int)
{
// the function to be handled, when a user starts the command
}

bool MyCommand::isActive(void)
{
// availability of the command (eg.: check for existence of a document,...)
// if this function returns False, the menu/ buttons are ßdisabled (gray)
return (hasActiveDocument() && !Gui::Control().activeDialog());
}
```
To register the command in FreeCAD:
```c++
#include <Gui/Command.h>
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new MyCommand());
```
Adding a item to a menu/toolbar:

if your command is added with python you have to run this code:
in src/module/Gui/AppModuleGui.cpp add to PyMOD_INIT_FUNC:

```c++
// try to instantiate a python module
try{
Base::Interpreter().runStringObject("import MyCommands");
} catch (Base::PyException &err){
err.ReportException();
}
```

and add the name of the command to a tooltip/menu in src/module/Gui/Workbench.cpp Workbench::setupToolBars


```c++
Gui::ToolBarItem* Workbench::setupToolBars() const
{
Gui::ToolBarItem* root = StdWorkbench::setupToolBars();
Gui::ToolBarItem* myToolbar = new Gui::ToolBarItem(root);
myToolbar->setCommand("my_commands");
*myToolbar << "MyCommand";
return root;
}
```
12 changes: 12 additions & 0 deletions freecad/the_experimental_workbench/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# coding: utf-8

r"""__init__.py for The Experimental Workbench.
The Experimental Workbench is a new/namespace workbench.
"""

from os.path import dirname, join
from .version import __version__

ICONPATH = join(dirname(__file__), "resources")
57 changes: 57 additions & 0 deletions freecad/the_experimental_workbench/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# coding: utf-8

r"""commands.py for The Experimental Workbench.
The Experimental Workbench is a new/namespace workbench.
"""

import os
import FreeCAD
import FreeCADGui as Gui
from PySide import QtCore, QtGui


class BaseCommand(object):
NAME = ""
ICONDIR = os.path.join(os.path.dirname(__file__), "resources")

def __init__(self):
pass

def IsActive(self):
if FreeCAD.ActiveDocument is None:
return False
else:
return True

def Activated(self):
diag = QtGui.QMessageBox(QtGui.QMessageBox.Information, 'Info MessageBox', f"I am command {self.NAME}")
diag.setWindowModality(QtCore.Qt.ApplicationModal)
diag.exec_()

def GetResources(self):
return {'Pixmap': self.Pixmap,
'MenuText': self.MenuText,
'ToolTip': self.ToolTip}


class Command1(BaseCommand):
NAME = "Command1"
Pixmap = os.path.join(BaseCommand.ICONDIR, 'command1.svg')
MenuText = 'Command 1'
ToolTip = 'Run Command 1'


class Command2(BaseCommand):
NAME = "Command2"
Pixmap = os.path.join(BaseCommand.ICONDIR, 'command2.svg')
MenuText = 'Command 2'
ToolTip = 'Run Command 2'


class Command3(BaseCommand):
NAME = "Command3"
Pixmap = os.path.join(BaseCommand.ICONDIR, 'command3.svg')
MenuText = 'Command 3'
ToolTip = 'Run Command 3'
59 changes: 59 additions & 0 deletions freecad/the_experimental_workbench/init_gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# coding: utf-8

r"""init_gui.py for The Experimental Workbench.
The Experimental Workbench is a new/namespace workbench.
"""

import os
import FreeCADGui as Gui
import FreeCAD as App
from freecad.the_experimental_workbench import ICONPATH


class TheExperimentalWorkbench(Gui.Workbench):
"""
class which gets initiated at startup of the gui
"""

MenuText = "The Experimental Workbench"
ToolTip = "A workbench used to experiment and learn"
Icon = os.path.join(ICONPATH, "the_experimental_workbench_icon.svg")
commands = [
"Command1",
"Command2",
"Command3"]

def GetClassName(self):
return "Gui::PythonWorkbench"

def Initialize(self):
"""
This function is called at the first activation of the workbench.
here is the place to import all the commands
"""
from freecad.the_experimental_workbench import my_numpy_function

from .commands import Command1, Command2, Command3

App.Console.PrintMessage("switching to workbench_starterkit\n")
App.Console.PrintMessage("run a numpy function: sqrt(100) = {}\n".format(my_numpy_function.my_foo(100)))

self.appendToolbar("Experimental WB", self.commands)
self.appendMenu("Experimental WB", self.commands)

Gui.addCommand('Command1', Command1())
Gui.addCommand('Command2', Command2())
Gui.addCommand('Command3', Command3())

def Activated(self):
"""Code which should be computed when a user switch to this workbench."""
pass

def Deactivated(self):
"""Code which should be computed when this workbench is deactivated."""
pass


Gui.addWorkbench(TheExperimentalWorkbench())
13 changes: 13 additions & 0 deletions freecad/the_experimental_workbench/my_numpy_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# coding: utf-8

r"""my_numpy_function.py for The Experimental Workbench.
The Experimental Workbench is a new/namespace workbench.
"""

import numpy as np


def my_foo(value):
return np.sqrt(value)
Loading

0 comments on commit 2bee6b9

Please sign in to comment.