Added core tool framework files + boost::context assembly stuff (initial, very buggy and unfinished work).
This commit is contained in:
parent
bd182aad9f
commit
241061025b
|
@ -144,11 +144,23 @@ set(COMMON_SRCS
|
|||
zoom.cpp
|
||||
)
|
||||
|
||||
enable_language(C CXX ASM)
|
||||
set_source_files_properties(system/fcontext.s PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp")
|
||||
|
||||
set(COMMON_SRCS
|
||||
${COMMON_SRCS}
|
||||
view/view.cpp
|
||||
view/view_item.cpp
|
||||
)
|
||||
|
||||
system/fcontext.s
|
||||
|
||||
tool/tool_base.cpp
|
||||
tool/tool_manager.cpp
|
||||
tool/tool_dispatcher.cpp
|
||||
tool/tool_event.cpp
|
||||
tool/tool_interactive.cpp
|
||||
tool/context_menu.cpp
|
||||
)
|
||||
|
||||
add_library(common STATIC ${COMMON_SRCS})
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Boost::Context assembly wrapper - done to avoid compiling the whole boost binary library
|
||||
which may be unpleasant, in particular under Windows (we don't support VC++, while boost::context
|
||||
does not support mingw */
|
||||
|
||||
|
||||
#if __i386__
|
||||
#include "jump_i386_sysv_elf_gas.S"
|
||||
#include "make_i386_sysv_elf_gas.S"
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include "jump_i386_pe_gas.S"
|
||||
#include "make_i386_pe_gas.S"
|
||||
#endif
|
||||
|
||||
#elif __x86_64__
|
||||
#include "jump_x86_64_sysv_elf_gas.S"
|
||||
#include "make_x86_64_sysv_elf_gas.S"
|
||||
#endif
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* Copyright Oliver Kowalke 2009.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 2
|
||||
.type jump_fcontext,@function
|
||||
|
||||
jump_fcontext:
|
||||
mov 0x4(%esp),%ecx
|
||||
mov %edi,(%ecx)
|
||||
mov %esi,0x4(%ecx)
|
||||
mov %ebx,0x8(%ecx)
|
||||
mov %ebp,0xc(%ecx)
|
||||
mov %fs:0x18,%edx
|
||||
mov (%edx),%eax
|
||||
mov %eax,0x24(%ecx)
|
||||
mov 0x4(%edx),%eax
|
||||
mov %eax,0x18(%ecx)
|
||||
mov 0x8(%edx),%eax
|
||||
mov %eax,0x20(%ecx)
|
||||
mov 0x10(%edx),%eax
|
||||
mov %eax,0x28(%ecx)
|
||||
lea 0x4(%esp),%eax
|
||||
mov %eax,0x10(%ecx)
|
||||
mov (%esp),%eax
|
||||
mov %eax,0x14(%ecx)
|
||||
mov 0x8(%esp),%edx
|
||||
mov (%edx),%edi
|
||||
mov 0x4(%edx),%esi
|
||||
mov 0x8(%edx),%ebx
|
||||
mov 0xc(%edx),%ebp
|
||||
mov 0x10(%esp),%eax
|
||||
test %eax,%eax
|
||||
je jump_fcontext+0x5f
|
||||
stmxcsr 0x2c(%ecx)
|
||||
fnstcw 0x30(%ecx)
|
||||
ldmxcsr 0x2c(%edx)
|
||||
fldcw 0x30(%edx)
|
||||
mov %edx,%ecx
|
||||
mov %fs:0x18,%edx
|
||||
mov 0x24(%ecx),%eax
|
||||
mov %eax,(%edx)
|
||||
mov 0x18(%ecx),%eax
|
||||
mov %eax,0x4(%edx)
|
||||
mov 0x20(%ecx),%eax
|
||||
mov %eax,0x8(%edx)
|
||||
mov 0x28(%ecx),%eax
|
||||
mov %eax,0x10(%edx)
|
||||
mov 0xc(%esp),%eax
|
||||
mov 0x10(%ecx),%esp
|
||||
mov %eax,0x4(%esp)
|
||||
mov 0x14(%ecx),%ecx
|
||||
jmp *%ecx
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/********************************************************************
|
||||
* *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | EDI | ESI | EBX | EBP | ESP | EIP | *
|
||||
* -------------------------------------------------------------- *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 6 | 7 | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0x18 | 0x1c | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | sp | size | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 8 | 9 | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| | *
|
||||
* -------------------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************************/
|
||||
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.align 2
|
||||
.type jump_fcontext,@function
|
||||
jump_fcontext:
|
||||
movl 0x4(%esp), %ecx /* load address of the first fcontext_t arg */
|
||||
movl %edi, (%ecx) /* save EDI */
|
||||
movl %esi, 0x4(%ecx) /* save ESI */
|
||||
movl %ebx, 0x8(%ecx) /* save EBX */
|
||||
movl %ebp, 0xc(%ecx) /* save EBP */
|
||||
|
||||
leal 0x4(%esp), %eax /* exclude the return address */
|
||||
movl %eax, 0x10(%ecx) /* save as stack pointer */
|
||||
movl (%esp), %eax /* load return address */
|
||||
movl %eax, 0x14(%ecx) /* save return address */
|
||||
|
||||
movl 0x8(%esp), %edx /* load address of the second fcontext_t arg */
|
||||
movl (%edx), %edi /* restore EDI */
|
||||
movl 0x4(%edx), %esi /* restore ESI */
|
||||
movl 0x8(%edx), %ebx /* restore EBX */
|
||||
movl 0xc(%edx), %ebp /* restore EBP */
|
||||
|
||||
movl 0x10(%esp), %eax /* check if fpu enve preserving was requested */
|
||||
test %eax, %eax
|
||||
je 1f
|
||||
|
||||
stmxcsr 0x20(%ecx) /* save MMX control and status word */
|
||||
fnstcw 0x24(%ecx) /* save x87 control word */
|
||||
ldmxcsr 0x20(%edx) /* restore MMX control and status word */
|
||||
fldcw 0x24(%edx) /* restore x87 control word */
|
||||
1:
|
||||
movl 0xc(%esp), %eax /* use third arg as return value after jump */
|
||||
|
||||
movl 0x10(%edx), %esp /* restore ESP */
|
||||
movl %eax, 0x4(%esp) /* use third arg as first arg in context function */
|
||||
movl 0x14(%edx), %edx /* fetch the address to return to */
|
||||
|
||||
jmp *%edx /* indirect jump to context */
|
||||
.size jump_fcontext,.-jump_fcontext
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | RBX | R12 | R13 | R14 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R15 | RBP | RSP | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x40 | 0x44 | 0x48 | 0x4c | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | sp | size | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 20 | 21 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x50 | 0x54 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* **************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl jump_fcontext
|
||||
.type jump_fcontext,@function
|
||||
.align 16
|
||||
jump_fcontext:
|
||||
movq %rbx, (%rdi) /* save RBX */
|
||||
movq %r12, 0x8(%rdi) /* save R12 */
|
||||
movq %r13, 0x10(%rdi) /* save R13 */
|
||||
movq %r14, 0x18(%rdi) /* save R14 */
|
||||
movq %r15, 0x20(%rdi) /* save R15 */
|
||||
movq %rbp, 0x28(%rdi) /* save RBP */
|
||||
|
||||
cmp $0, %rcx
|
||||
je 1f
|
||||
|
||||
stmxcsr 0x50(%rdi) /* save MMX control and status word */
|
||||
fnstcw 0x54(%rdi) /* save x87 control word */
|
||||
|
||||
ldmxcsr 0x50(%rsi) /* restore MMX control and status word */
|
||||
fldcw 0x54(%rsi) /* restore x87 control word */
|
||||
1:
|
||||
|
||||
leaq 0x8(%rsp), %rax /* exclude the return address and save as stack pointer */
|
||||
movq %rax, 0x30(%rdi) /* save as stack pointer */
|
||||
movq (%rsp), %rax /* save return address */
|
||||
movq %rax, 0x38(%rdi) /* save return address as RIP */
|
||||
|
||||
movq (%rsi), %rbx /* restore RBX */
|
||||
movq 0x8(%rsi), %r12 /* restore R12 */
|
||||
movq 0x10(%rsi), %r13 /* restore R13 */
|
||||
movq 0x18(%rsi), %r14 /* restore R14 */
|
||||
movq 0x20(%rsi), %r15 /* restore R15 */
|
||||
movq 0x28(%rsi), %rbp /* restore RBP */
|
||||
|
||||
movq 0x30(%rsi), %rsp /* restore RSP */
|
||||
movq 0x38(%rsi), %rcx /* fetch the address to return to */
|
||||
|
||||
movq %rdx, %rax /* use third arg as return value after jump */
|
||||
movq %rdx, %rdi /* use third arg as first arg in context function */
|
||||
|
||||
jmp *%rcx /* indirect jump to context */
|
||||
.size jump_fcontext,.-jump_fcontext
|
|
@ -0,0 +1,54 @@
|
|||
/* Copyright Oliver Kowalke 2009.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 2
|
||||
.type make_fcontext,@function
|
||||
|
||||
make_fcontext:
|
||||
mov 0x4(%esp),%eax
|
||||
lea -0x34(%eax),%eax
|
||||
and $0xfffffff0,%eax
|
||||
mov 0x4(%esp),%ecx
|
||||
mov %ecx,0x18(%eax)
|
||||
mov 0x8(%esp),%edx
|
||||
mov %edx,0x1c(%eax)
|
||||
neg %edx
|
||||
lea (%edx,%ecx,1),%ecx
|
||||
mov %ecx,0x20(%eax)
|
||||
mov 0xc(%esp),%ecx
|
||||
mov %ecx,0x14(%eax)
|
||||
stmxcsr 0x2c(%eax)
|
||||
fnstcw 0x30(%eax)
|
||||
lea -0x1c(%eax),%edx
|
||||
mov %edx,0x10(%eax)
|
||||
mov $0x0,%ecx
|
||||
mov %ecx,(%edx)
|
||||
mov %fs:0x18,%ecx
|
||||
mov (%ecx),%edx
|
||||
inc %edx
|
||||
je make_fcontext+0x4c // <_make_fcontext+0x4c>
|
||||
dec %edx
|
||||
xchg %edx,%ecx
|
||||
jmp make_fcontext+0x42 // <_make_fcontext+0x42>
|
||||
mov 0x4(%ecx),%ecx
|
||||
mov 0x10(%eax),%edx
|
||||
mov %ecx,0x18(%edx)
|
||||
mov $0xffffffff,%ecx
|
||||
mov %ecx,0x14(%edx)
|
||||
lea 0x14(%edx),%ecx
|
||||
mov %ecx,0x24(%eax)
|
||||
ret
|
||||
|
||||
finish:
|
||||
xor %eax,%eax
|
||||
mov %eax,(%esp)
|
||||
call finish+0xa
|
||||
hlt
|
||||
|
||||
.size make_fcontext,.-make_fcontext
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/********************************************************************
|
||||
* *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | EDI | ESI | EBX | EBP | ESP | EIP | *
|
||||
* -------------------------------------------------------------- *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 6 | 7 | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0x18 | 0x1c | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | sp | size | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 8 | 9 | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | | *
|
||||
* -------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| | *
|
||||
* -------------------------------------------------------------- *
|
||||
* *
|
||||
* *****************************************************************/
|
||||
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.align 2
|
||||
.type make_fcontext,@function
|
||||
make_fcontext:
|
||||
movl 0x4(%esp), %eax /* load 1. arg of make_fcontext, pointer to context stack (base) */
|
||||
leal -0x28(%eax), %eax /* reserve space for fcontext_t at top of context stack */
|
||||
|
||||
/* shift address in EAX to lower 16 byte boundary */
|
||||
/* == pointer to fcontext_t and address of context stack */
|
||||
andl $-16, %eax
|
||||
|
||||
movl 0x4(%esp), %edx /* load 1. arg of make_fcontext, pointer to context stack (base) */
|
||||
movl %edx, 0x18(%eax) /* save address of context stack (base) in fcontext_t */
|
||||
movl 0x8(%esp), %edx /* load 2. arg of make_fcontext, context stack size */
|
||||
movl %edx, 0x1c(%eax) /* save stack size in fcontext_t */
|
||||
movl 0xc(%esp), %edx /* load 3. arg of make_fcontext, pointer to context function */
|
||||
movl %edx, 0x14(%eax) /* save address of context function in fcontext_t */
|
||||
|
||||
stmxcsr 0x20(%eax) /* save MMX control and status word */
|
||||
fnstcw 0x24(%eax) /* save x87 control word */
|
||||
|
||||
leal -0x8(%eax), %edx /* reserve space for the last frame on context stack; (ESP - 0x4) % 16 == 0 */
|
||||
movl %edx, 0x10(%eax) /* save address in EDX as stack pointer for context function */
|
||||
|
||||
call 1f
|
||||
1: popl %ecx /* address of label 2 */
|
||||
addl $finish-1b, %ecx /* compute abs address of label finish */
|
||||
movl %ecx, (%edx) /* save address of finish as return address for context functions */
|
||||
/* entered after context function returns */
|
||||
|
||||
ret
|
||||
|
||||
finish:
|
||||
/* ESP points to same address as ESP on entry of context function + 0x4 */
|
||||
call 2f
|
||||
2: popl %ebx /* address of label 3 */
|
||||
addl $_GLOBAL_OFFSET_TABLE_+[.-2b], %ebx /* compute address of GOT and store it in EBX */
|
||||
|
||||
xorl %eax, %eax
|
||||
movl %eax, (%esp) /* exit code is zero */
|
||||
call _exit@PLT /* exit application */
|
||||
hlt
|
||||
.size make_fcontext,.-make_fcontext
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright Oliver Kowalke 2009.
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
/****************************************************************************************
|
||||
* *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x0 | 0x4 | 0x8 | 0xc | 0x10 | 0x14 | 0x18 | 0x1c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | RBX | R12 | R13 | R14 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x20 | 0x24 | 0x28 | 0x2c | 0x30 | 0x34 | 0x38 | 0x3c | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | R15 | RBP | RSP | RIP | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 16 | 17 | 18 | 19 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x40 | 0x44 | 0x48 | 0x4c | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | sp | size | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 20 | 21 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | 0x50 | 0x54 | | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* | fc_mxcsr|fc_x87_cw| | *
|
||||
* ---------------------------------------------------------------------------------- *
|
||||
* *
|
||||
* **************************************************************************************/
|
||||
|
||||
.text
|
||||
.globl make_fcontext
|
||||
.type make_fcontext,@function
|
||||
.align 16
|
||||
make_fcontext:
|
||||
leaq -0x58(%rdi), %rax /* reserve space for fcontext_t at top of context stack */
|
||||
|
||||
/* shift address in RAX to lower 16 byte boundary */
|
||||
/* == pointer to fcontext_t and address of context stack */
|
||||
andq $-16, %rax
|
||||
|
||||
movq %rdi, 0x40(%rax) /* save address of context stack pointer (base) in fcontext_t */
|
||||
movq %rsi, 0x48(%rax) /* save context stack size in fcontext_t */
|
||||
movq %rdx, 0x38(%rax) /* save address of context function in fcontext_t */
|
||||
|
||||
stmxcsr 0x50(%rax) /* save MMX control and status word */
|
||||
fnstcw 0x54(%rax) /* save x87 control word */
|
||||
|
||||
leaq -0x8(%rax), %rdx /* reserve space for the return address on context stack, (RSP - 0x8) % 16 == 0 */
|
||||
movq %rdx, 0x30(%rax) /* save address in RDX as stack pointer for context function */
|
||||
|
||||
leaq finish(%rip), %rcx /* compute abs address of label finish */
|
||||
movq %rcx, (%rdx) /* save address of finish as return address for context function */
|
||||
/* entered after context function returns */
|
||||
|
||||
ret /* return pointer to fcontext_t placed on context stack */
|
||||
|
||||
finish:
|
||||
/* RSP points to same address as RSP on entry of context function + 0x8 */
|
||||
xorq %rdi, %rdi /* exit code is zero */
|
||||
call _exit@PLT /* exit application */
|
||||
hlt
|
||||
.size make_fcontext,.-make_fcontext
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#include <wx/wx.h>
|
||||
#include <wx/menu.h>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_interactive.h>
|
||||
|
||||
#include <tool/context_menu.h>
|
||||
|
||||
class CONTEXT_MENU::CMEventHandler : public wxEvtHandler
|
||||
{
|
||||
public:
|
||||
CMEventHandler( CONTEXT_MENU *aMenu ):
|
||||
m_menu(aMenu) {};
|
||||
|
||||
void onEvent( wxEvent & aEvent )
|
||||
{
|
||||
TOOL_EVENT evt;
|
||||
wxEventType type = aEvent.GetEventType();
|
||||
|
||||
if(type == wxEVT_MENU_HIGHLIGHT)
|
||||
evt = TOOL_EVENT (TC_Command, TA_ContextMenuUpdate, aEvent.GetId() );
|
||||
else if (type == wxEVT_COMMAND_MENU_SELECTED)
|
||||
evt = TOOL_EVENT (TC_Command, TA_ContextMenuChoice, aEvent.GetId() );
|
||||
|
||||
m_menu->m_tool->GetManager()->ProcessEvent(evt);
|
||||
}
|
||||
|
||||
private:
|
||||
CONTEXT_MENU *m_menu;
|
||||
};
|
||||
|
||||
|
||||
CONTEXT_MENU::CONTEXT_MENU ( )
|
||||
{
|
||||
m_tool = NULL;
|
||||
m_menu = new wxMenu();
|
||||
m_handler = new CMEventHandler(this);
|
||||
m_menu->Connect (wxEVT_MENU_HIGHLIGHT, wxEventHandler( CMEventHandler::onEvent ), NULL, m_handler );
|
||||
m_menu->Connect (wxEVT_COMMAND_MENU_SELECTED, wxEventHandler( CMEventHandler::onEvent ), NULL, m_handler );
|
||||
m_titleSet = false;
|
||||
}
|
||||
|
||||
CONTEXT_MENU::~CONTEXT_MENU ( )
|
||||
{
|
||||
delete m_menu;
|
||||
delete m_handler;
|
||||
}
|
||||
|
||||
void CONTEXT_MENU::SetTitle( const wxString& aTitle )
|
||||
{
|
||||
if(m_titleSet)
|
||||
{
|
||||
m_menu->Delete(m_menu->FindItemByPosition(0)); // fixme: this is LAME!
|
||||
m_menu->Delete(m_menu->FindItemByPosition(0));
|
||||
}
|
||||
|
||||
m_menu->InsertSeparator(0);
|
||||
m_menu->Insert(0, new wxMenuItem( m_menu, -1, aTitle, wxEmptyString, wxITEM_NORMAL ) );
|
||||
m_titleSet = true;
|
||||
}
|
||||
|
||||
void CONTEXT_MENU::Add ( const wxString& aItem, int aId )
|
||||
{
|
||||
m_menu->Append( new wxMenuItem( m_menu, aId, aItem, wxEmptyString, wxITEM_NORMAL ) );
|
||||
}
|
||||
|
||||
void CONTEXT_MENU::Clear()
|
||||
{
|
||||
m_titleSet = false;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
||||
KiGfx::VIEW *TOOL_BASE::getView()
|
||||
{
|
||||
return m_toolMgr->GetView();
|
||||
}
|
||||
|
||||
KiGfx::VIEW_CONTROLS *TOOL_BASE::getViewControls()
|
||||
{
|
||||
return m_toolMgr->GetViewControls();
|
||||
}
|
||||
|
||||
wxWindow * TOOL_BASE::getEditFrameInt()
|
||||
{
|
||||
return m_toolMgr->GetEditFrame();
|
||||
}
|
||||
|
||||
EDA_ITEM * TOOL_BASE::getModelInt()
|
||||
{
|
||||
return m_toolMgr->GetModel();
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
#include <wx/wx.h>
|
||||
#include <wx/event.h>
|
||||
|
||||
#include <wxPcbStruct.h>
|
||||
#include <wxBasePcbFrame.h>
|
||||
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
#include <view/view.h>
|
||||
|
||||
#include <class_drawpanel_gal.h>
|
||||
|
||||
#include <pcbnew_id.h>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using boost::optional;
|
||||
|
||||
struct TOOL_DISPATCHER::ButtonState
|
||||
{
|
||||
|
||||
ButtonState (TOOL_MouseButtons aButton, const wxEventType& aDownEvent, const wxEventType & aUpEvent, bool aTriggerMenu = false) :
|
||||
button(aButton),
|
||||
downEvent(aDownEvent),
|
||||
upEvent(aUpEvent),
|
||||
triggerContextMenu(aTriggerMenu)
|
||||
{};
|
||||
|
||||
bool dragging;
|
||||
bool pressed;
|
||||
|
||||
VECTOR2D dragOrigin;
|
||||
double dragMaxDelta;
|
||||
|
||||
TOOL_MouseButtons button;
|
||||
wxEventType downEvent;
|
||||
wxEventType upEvent;
|
||||
bool triggerContextMenu;
|
||||
|
||||
wxLongLong downTimestamp;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
dragging = false;
|
||||
pressed = false;
|
||||
}
|
||||
};
|
||||
|
||||
TOOL_DISPATCHER::TOOL_DISPATCHER( TOOL_MANAGER *aToolMgr, PCB_BASE_FRAME *aEditFrame ):
|
||||
m_toolMgr(aToolMgr),
|
||||
m_editFrame(aEditFrame)
|
||||
{
|
||||
|
||||
m_buttons.push_back(new ButtonState(MB_Left, wxEVT_LEFT_DOWN, wxEVT_LEFT_UP));
|
||||
m_buttons.push_back(new ButtonState(MB_Right, wxEVT_RIGHT_DOWN, wxEVT_RIGHT_UP, true));
|
||||
m_buttons.push_back(new ButtonState(MB_Middle, wxEVT_MIDDLE_DOWN, wxEVT_MIDDLE_UP));
|
||||
|
||||
ResetState();
|
||||
};
|
||||
|
||||
TOOL_DISPATCHER::~TOOL_DISPATCHER()
|
||||
{
|
||||
BOOST_FOREACH(ButtonState *st, m_buttons)
|
||||
delete st;
|
||||
}
|
||||
|
||||
void TOOL_DISPATCHER::ResetState()
|
||||
{
|
||||
BOOST_FOREACH(ButtonState *st, m_buttons)
|
||||
st->Reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
KiGfx::VIEW* TOOL_DISPATCHER::getView()
|
||||
{
|
||||
return m_editFrame->GetGalCanvas()->GetView();
|
||||
}
|
||||
|
||||
int TOOL_DISPATCHER::decodeModifiers( wxEvent& aEvent )
|
||||
{
|
||||
wxMouseEvent *me = static_cast<wxMouseEvent*> (&aEvent);
|
||||
int mods = 0;
|
||||
|
||||
if(me->ControlDown())
|
||||
mods |= MB_ModCtrl;
|
||||
if(me->AltDown())
|
||||
mods |= MB_ModAlt;
|
||||
if(me->ShiftDown())
|
||||
mods |= MB_ModShift;
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
bool TOOL_DISPATCHER::handleMouseButton ( wxEvent& aEvent, int aIndex, bool aMotion )
|
||||
{
|
||||
ButtonState *st = m_buttons[aIndex];
|
||||
wxEventType type = aEvent.GetEventType();
|
||||
optional<TOOL_EVENT> evt;
|
||||
|
||||
bool up = type == st->upEvent;
|
||||
bool down = type == st->downEvent;
|
||||
|
||||
int mods = decodeModifiers(aEvent);
|
||||
int args = st->button | mods;
|
||||
|
||||
if(down)
|
||||
{
|
||||
st->downTimestamp = wxGetLocalTimeMillis();
|
||||
st->dragOrigin = m_lastMousePos;
|
||||
st->dragMaxDelta = 0;
|
||||
st->pressed = true;
|
||||
evt = TOOL_EVENT (TC_Mouse, TA_MouseDown, args );
|
||||
} else if (up)
|
||||
{
|
||||
bool isClick = false;
|
||||
st->pressed = false;
|
||||
|
||||
if(st->dragging)
|
||||
{
|
||||
wxLongLong t = wxGetLocalTimeMillis();
|
||||
|
||||
if( t - st->downTimestamp < DragTimeThreshold && st->dragMaxDelta < DragDistanceThreshold )
|
||||
isClick = true;
|
||||
else
|
||||
evt = TOOL_EVENT (TC_Mouse, TA_MouseUp, args );
|
||||
} else
|
||||
isClick = true;
|
||||
|
||||
|
||||
if(isClick)
|
||||
{
|
||||
if(st -> triggerContextMenu && !mods)
|
||||
{}
|
||||
// evt = TOOL_EVENT (TC_Command, TA_ContextMenu );
|
||||
else
|
||||
evt = TOOL_EVENT (TC_Mouse, TA_MouseClick, args );
|
||||
}
|
||||
|
||||
st->dragging = false;
|
||||
}
|
||||
|
||||
if(st->pressed && aMotion)
|
||||
{
|
||||
st->dragging = true;
|
||||
double dragPixelDistance = getView()->ToScreen(m_lastMousePos - st->dragOrigin, false).EuclideanNorm();
|
||||
st->dragMaxDelta = std::max(st->dragMaxDelta, dragPixelDistance);
|
||||
|
||||
wxLongLong t = wxGetLocalTimeMillis();
|
||||
|
||||
if( t - st->downTimestamp > DragTimeThreshold || st->dragMaxDelta > DragDistanceThreshold )
|
||||
{
|
||||
evt = TOOL_EVENT (TC_Mouse, TA_MouseDrag, args );
|
||||
evt->SetMouseDragOrigin(st->dragOrigin);
|
||||
evt->SetMouseDelta(m_lastMousePos - st->dragOrigin);
|
||||
}
|
||||
}
|
||||
|
||||
if(evt)
|
||||
{
|
||||
evt->SetMousePosition(m_lastMousePos);
|
||||
m_toolMgr->ProcessEvent( *evt );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TOOL_DISPATCHER::DispatchWxEvent(wxEvent &aEvent)
|
||||
{
|
||||
bool motion = false, buttonEvents = false;
|
||||
VECTOR2D pos;
|
||||
optional<TOOL_EVENT> evt;
|
||||
|
||||
int type = aEvent.GetEventType();
|
||||
|
||||
if( type == wxEVT_MOTION )
|
||||
{
|
||||
wxMouseEvent *me = static_cast<wxMouseEvent*> (&aEvent);
|
||||
pos = getView()->ToWorld ( VECTOR2D( me->GetX(), me->GetY() ));
|
||||
if(pos != m_lastMousePos)
|
||||
{
|
||||
motion = true;
|
||||
m_lastMousePos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < m_buttons.size(); i++)
|
||||
buttonEvents |= handleMouseButton(aEvent, i, motion);
|
||||
|
||||
if(!buttonEvents && motion)
|
||||
{
|
||||
evt = TOOL_EVENT (TC_Mouse, TA_MouseMotion );
|
||||
evt->SetMousePosition(pos);
|
||||
}
|
||||
|
||||
if(evt)
|
||||
m_toolMgr->ProcessEvent( *evt );
|
||||
|
||||
aEvent.Skip();
|
||||
|
||||
}
|
||||
|
||||
void TOOL_DISPATCHER::DispatchWxCommand(wxCommandEvent &aEvent)
|
||||
{
|
||||
bool activateTool = false;
|
||||
std::string toolName;
|
||||
|
||||
switch (aEvent.GetId())
|
||||
{
|
||||
case ID_SELECTION_TOOL:
|
||||
toolName = "pcbnew.InteractiveSelection";
|
||||
activateTool = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(activateTool)
|
||||
{
|
||||
TOOL_EVENT evt ( TC_Command, TA_ActivateTool, toolName );
|
||||
m_toolMgr->ProcessEvent(evt);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include <base_struct.h>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct FlagString {
|
||||
int flag;
|
||||
std::string str;
|
||||
};
|
||||
|
||||
static const std::string flag2string(int flag, const FlagString *exps)
|
||||
{
|
||||
std::string rv;
|
||||
for(int i = 0; exps[i].str.length(); i++)
|
||||
if(exps[i].flag & flag)
|
||||
rv+=exps[i].str+" ";
|
||||
return rv;
|
||||
}
|
||||
|
||||
const std::string TOOL_EVENT::Format() const
|
||||
{
|
||||
std::string ev;
|
||||
|
||||
const FlagString categories[] = {
|
||||
{TC_Mouse, "mouse"},
|
||||
{TC_Command, "command"},
|
||||
{TC_Message, "message"},
|
||||
{TC_View, "view"},
|
||||
{0, ""}
|
||||
};
|
||||
|
||||
const FlagString actions[] = {
|
||||
{TA_MouseClick, "click"},
|
||||
{TA_MouseUp, "button-up"},
|
||||
{TA_MouseDown, "button-down"},
|
||||
{TA_MouseDrag, "drag"},
|
||||
{TA_MouseMotion, "motion"},
|
||||
{TA_MouseWheel, "wheel"},
|
||||
{TA_ViewRefresh, "view-refresh"},
|
||||
{TA_ViewZoom, "view-zoom"},
|
||||
{TA_ViewPan, "view-pan"},
|
||||
{TA_ViewDirty, "view-dirty"},
|
||||
{TA_ChangeLayer, "change-layer"},
|
||||
{TA_CancelTool, "cancel-tool"},
|
||||
{TA_ActivateTool, "activate-tool"},
|
||||
{TA_ContextMenuUpdate, "context-menu-update"},
|
||||
{TA_ContextMenuChoice, "context-menu-choice"},
|
||||
{0, ""}
|
||||
};
|
||||
|
||||
const FlagString buttons[] = {
|
||||
{MB_None, "none"},
|
||||
{MB_Left, "left"},
|
||||
{MB_Right, "right"},
|
||||
{MB_Middle, "middle"},
|
||||
{MB_ModShift, "shift"},
|
||||
{MB_ModCtrl, "ctrl"},
|
||||
{MB_ModAlt, "alt"},
|
||||
{0, ""}
|
||||
};
|
||||
|
||||
ev = "category: ";
|
||||
ev += flag2string(m_category, categories);
|
||||
ev +=" action: ";
|
||||
ev += flag2string(m_actions, actions);
|
||||
|
||||
if(m_actions & TA_Mouse)
|
||||
{
|
||||
ev +=" btns: ";
|
||||
ev += flag2string(m_mouseButtons, buttons);
|
||||
};
|
||||
|
||||
if(m_commandId)
|
||||
{
|
||||
char tmp[128];
|
||||
sprintf(tmp,"cmd-id: %d", *m_commandId);
|
||||
ev += tmp;
|
||||
}
|
||||
|
||||
if(m_commandStr)
|
||||
ev += "cmd-str: " + (*m_commandStr);
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
const std::string TOOL_EVENT_LIST::Format() const
|
||||
{
|
||||
string s;
|
||||
|
||||
BOOST_FOREACH(TOOL_EVENT e, m_events)
|
||||
s+=e.Format()+" ";
|
||||
|
||||
return s;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
#include <string>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_interactive.h>
|
||||
#include <tool/context_menu.h>
|
||||
|
||||
TOOL_INTERACTIVE::TOOL_INTERACTIVE( TOOL_ID aId, const std::string& aName ):
|
||||
TOOL_BASE(TOOL_Interactive, aId, aName)
|
||||
{};
|
||||
|
||||
TOOL_INTERACTIVE::TOOL_INTERACTIVE( const std::string& aName ):
|
||||
TOOL_BASE(TOOL_Interactive, TOOL_MANAGER::MakeToolId(aName), aName)
|
||||
{};
|
||||
|
||||
|
||||
TOOL_INTERACTIVE::~TOOL_INTERACTIVE()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OPT_TOOL_EVENT TOOL_INTERACTIVE::Wait ( const TOOL_EVENT_LIST & aEventList )
|
||||
{
|
||||
return m_toolMgr->ScheduleWait(this, aEventList);
|
||||
}
|
||||
|
||||
void TOOL_INTERACTIVE::goInternal( TOOL_STATE_FUNC& aState, const TOOL_EVENT_LIST& aConditions )
|
||||
{
|
||||
m_toolMgr->ScheduleNextState(this, aState, aConditions);
|
||||
}
|
||||
|
||||
void TOOL_INTERACTIVE::Reset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TOOL_INTERACTIVE::SetContextMenu( CONTEXT_MENU *aMenu, TOOL_ContextMenuTrigger aTrigger )
|
||||
{
|
||||
aMenu->setTool(this);
|
||||
m_toolMgr->ScheduleContextMenu(this, aMenu, aTrigger);
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
#include <map>
|
||||
#include <deque>
|
||||
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
#include <view/view.h>
|
||||
|
||||
#include <tool/tool_base.h>
|
||||
#include <tool/tool_interactive.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/context_menu.h>
|
||||
#include <tool/coroutine.h>
|
||||
|
||||
#include <wxPcbStruct.h>
|
||||
#include <class_drawpanel_gal.h>
|
||||
|
||||
using boost::optional;
|
||||
using namespace std;
|
||||
|
||||
struct TOOL_MANAGER::ToolState
|
||||
{
|
||||
TOOL_BASE *theTool;
|
||||
|
||||
bool idle;
|
||||
bool pendingWait;
|
||||
bool pendingContextMenu;
|
||||
|
||||
CONTEXT_MENU *contextMenu;
|
||||
TOOL_ContextMenuTrigger contextMenuTrigger;
|
||||
|
||||
COROUTINE<int, TOOL_EVENT&> *cofunc;
|
||||
|
||||
TOOL_EVENT wakeupEvent;
|
||||
TOOL_EVENT_LIST waitEvents;
|
||||
|
||||
std::vector<Transition> transitions;
|
||||
|
||||
|
||||
};
|
||||
|
||||
TOOL_MANAGER::TOOL_MANAGER()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TOOL_MANAGER::RegisterTool ( TOOL_BASE *aTool )
|
||||
{
|
||||
ToolState *st = new ToolState;
|
||||
|
||||
st->theTool = aTool;
|
||||
st->idle = true;
|
||||
st->pendingWait = false;
|
||||
st->pendingContextMenu = false;
|
||||
st->cofunc = NULL;
|
||||
st->contextMenuTrigger = CMENU_OFF;
|
||||
|
||||
m_toolState[ aTool ] = st;
|
||||
m_toolNameIndex [ aTool->GetName() ] = st;
|
||||
m_toolIdIndex [ aTool->GetId() ] = st;
|
||||
|
||||
aTool->m_toolMgr = this;
|
||||
|
||||
if(aTool->GetType() == TOOL_Interactive)
|
||||
static_cast<TOOL_INTERACTIVE*>(aTool)->Reset();
|
||||
}
|
||||
|
||||
void TOOL_MANAGER::ScheduleNextState( TOOL_BASE *aTool, TOOL_STATE_FUNC& aHandler, const TOOL_EVENT_LIST & aConditions )
|
||||
{
|
||||
ToolState *st = m_toolState [aTool];
|
||||
st->transitions.push_back ( Transition (aConditions, aHandler ));
|
||||
}
|
||||
|
||||
optional<TOOL_EVENT> TOOL_MANAGER::ScheduleWait( TOOL_BASE *aTool, const TOOL_EVENT_LIST & aConditions )
|
||||
{
|
||||
ToolState *st = m_toolState [aTool];
|
||||
|
||||
st->pendingWait = true;
|
||||
st->waitEvents = aConditions;
|
||||
st->cofunc->Yield();
|
||||
|
||||
return st->wakeupEvent;
|
||||
}
|
||||
|
||||
void TOOL_MANAGER::dispatchInternal ( TOOL_EVENT& aEvent )
|
||||
{
|
||||
// iterate over all registered tools
|
||||
BOOST_FOREACH(ToolState *st, m_toolState | boost::adaptors::map_values)
|
||||
{
|
||||
// the tool state handler is waiting for events (i.e. called Wait() method)
|
||||
if(st->pendingWait)
|
||||
{
|
||||
|
||||
if( st->waitEvents.Matches(aEvent) )
|
||||
{
|
||||
// got matching event? clear wait list and wake up the coroutine
|
||||
st->wakeupEvent = aEvent;
|
||||
st->pendingWait = false;
|
||||
st->waitEvents.clear();
|
||||
st->cofunc->Resume();
|
||||
if(!st->cofunc->Running())
|
||||
delete st->cofunc;
|
||||
|
||||
}
|
||||
} else {
|
||||
// no state handler in progress - check if there are any transitions (defined by
|
||||
// Go() method that match the event.
|
||||
|
||||
if(st->transitions.size()) {
|
||||
BOOST_FOREACH(Transition tr, st->transitions)
|
||||
{
|
||||
if(tr.first.Matches(aEvent))
|
||||
{
|
||||
st->transitions.clear();
|
||||
|
||||
if(!st->cofunc)
|
||||
st->cofunc = new COROUTINE<int, TOOL_EVENT&>( tr.second );
|
||||
else
|
||||
st->cofunc->SetEntry( tr.second );
|
||||
|
||||
// got match? Run the handler.
|
||||
st->cofunc->Call(aEvent);
|
||||
|
||||
if(!st->cofunc->Running())
|
||||
delete st->cofunc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TOOL_MANAGER::ProcessEvent (TOOL_EVENT& aEvent)
|
||||
{
|
||||
printf("process: %s\n", aEvent.Format().c_str());
|
||||
|
||||
dispatchInternal(aEvent);
|
||||
|
||||
|
||||
BOOST_FOREACH(ToolState *st, m_toolState | boost::adaptors::map_values)
|
||||
{
|
||||
if(st->contextMenuTrigger == CMENU_NOW)
|
||||
{
|
||||
st->pendingWait = true;
|
||||
st->waitEvents = TOOL_EVENT ( TC_Any, TA_Any );
|
||||
st->contextMenuTrigger = CMENU_OFF;
|
||||
GetEditFrame()->PopupMenu( st->contextMenu->GetMenu() );
|
||||
|
||||
TOOL_EVENT evt ( TC_Command, TA_ContextMenuChoice );
|
||||
dispatchInternal( evt );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_view->IsDirty())
|
||||
{
|
||||
PCB_EDIT_FRAME *f = static_cast<PCB_EDIT_FRAME*>(GetEditFrame());
|
||||
f->GetGalCanvas()->Refresh(); // fixme: ugly hack, provide a method in TOOL_DISPATCHER.
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TOOL_MANAGER::ScheduleContextMenu( TOOL_BASE *aTool, CONTEXT_MENU *aMenu, TOOL_ContextMenuTrigger aTrigger )
|
||||
{
|
||||
ToolState *st = m_toolState [aTool];
|
||||
|
||||
st->contextMenu = aMenu;
|
||||
st->contextMenuTrigger = aTrigger;
|
||||
|
||||
if(aTrigger == CMENU_NOW)
|
||||
st->cofunc->Yield();
|
||||
}
|
||||
|
||||
TOOL_ID TOOL_MANAGER::MakeToolId( const std::string &aToolName )
|
||||
{
|
||||
static int currentId;
|
||||
return currentId++;
|
||||
}
|
||||
|
||||
void TOOL_MANAGER::SetEnvironment( EDA_ITEM *aModel, KiGfx::VIEW* aView, KiGfx::VIEW_CONTROLS *aViewControls, wxWindow *aFrame )
|
||||
{
|
||||
m_model = aModel;
|
||||
m_view = aView;
|
||||
m_viewControls = aViewControls;
|
||||
m_editFrame = aFrame;
|
||||
// fixme: reset tools after changing environment
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __CONTEXT_MENU_H
|
||||
#define __CONTEXT_MENU_H
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
class wxMenu;
|
||||
class TOOL_INTERACTIVE;
|
||||
|
||||
/**
|
||||
* Class CONTEXT_MENU
|
||||
*
|
||||
* Defines the structure of a context (usually right-click) popup menu
|
||||
* for a given tool.
|
||||
*/
|
||||
class CONTEXT_MENU
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
CONTEXT_MENU ( );
|
||||
~CONTEXT_MENU ( );
|
||||
|
||||
void SetTitle( const wxString& aTitle );
|
||||
void Add ( const wxString& aItem, int aId );
|
||||
|
||||
// fixme: unimplemented
|
||||
// void Add ( const TOOL_ACTION& aAction, int aId = -1 );
|
||||
|
||||
void Clear();
|
||||
|
||||
wxMenu *GetMenu() const
|
||||
{
|
||||
return m_menu;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class CMEventHandler;
|
||||
|
||||
friend class TOOL_INTERACTIVE;
|
||||
|
||||
void setTool ( TOOL_INTERACTIVE *aTool )
|
||||
{
|
||||
m_tool = aTool;
|
||||
}
|
||||
|
||||
bool m_titleSet;
|
||||
|
||||
wxMenu *m_menu;
|
||||
CMEventHandler *m_handler;
|
||||
TOOL_INTERACTIVE *m_tool;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __COROUTINE_H
|
||||
#define __COROUTINE_H
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <boost/context/fcontext.hpp>
|
||||
|
||||
#include "delegate.h"
|
||||
|
||||
/**
|
||||
Class COROUNTINE.
|
||||
Implements a coroutine. Wikipedia has a good explanation:
|
||||
|
||||
"Coroutines are computer program components that generalize subroutines to
|
||||
allow multiple entry points for suspending and resuming execution at certain locations.
|
||||
Coroutines are well-suited for implementing more familiar program components such as cooperative
|
||||
tasks, exceptions, event loop, iterators, infinite lists and pipes."
|
||||
|
||||
In other words, a coroutine can be considered a lightweight thread - which can be
|
||||
preempted only when it deliberately yields the control to the caller. This way,
|
||||
we avoid concurrency problems such as locking / race conditions.
|
||||
|
||||
Uses boost::context library to do the actual context switching.
|
||||
|
||||
This particular version takes a DELEGATE as an entry point, so it can invoke
|
||||
methods within a given object as separate coroutines.
|
||||
|
||||
See coroutine_example.cpp for sample code.
|
||||
*/
|
||||
|
||||
template<class ReturnType, class ArgType >
|
||||
class COROUTINE {
|
||||
|
||||
public:
|
||||
|
||||
COROUTINE ( )
|
||||
{
|
||||
m_stackSize = c_defaultStackSize;
|
||||
m_stack = NULL;
|
||||
m_saved = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a coroutine from a member method of an object
|
||||
*/
|
||||
|
||||
template<class T>
|
||||
COROUTINE ( T* object, ReturnType (T::*ptr)( ArgType ) ) :
|
||||
m_func (object, ptr),
|
||||
m_saved(NULL),
|
||||
m_stack(NULL),
|
||||
m_stackSize(c_defaultStackSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Creates a coroutine from a delegate object
|
||||
*/
|
||||
COROUTINE( DELEGATE < ReturnType, ArgType > aEntry ) :
|
||||
m_func(aEntry),
|
||||
m_saved(NULL),
|
||||
m_stack(NULL),
|
||||
m_stackSize(c_defaultStackSize)
|
||||
{};
|
||||
|
||||
~COROUTINE()
|
||||
{
|
||||
if(m_saved)
|
||||
delete m_saved;
|
||||
if(m_stack)
|
||||
free(m_stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Yield()
|
||||
*
|
||||
* Stops execution of the coroutine and returns control to the caller.
|
||||
* After a yield, Call() or Resume() methods invoked by the caller will
|
||||
* immediately return true, indicating that we are not done yet, just asleep.
|
||||
*/
|
||||
void Yield( )
|
||||
{
|
||||
jump_fcontext(m_self, m_saved, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Yield()
|
||||
*
|
||||
* Yield with a value - passes a value of given type to the caller.
|
||||
* Useful for implementing generator objects.
|
||||
*/
|
||||
void Yield( ReturnType& retVal )
|
||||
{
|
||||
m_retVal = retVal;
|
||||
jump_fcontext(m_self, m_saved, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetEntry()
|
||||
*
|
||||
* Defines the entry point for the coroutine, if not set in the constructor.
|
||||
*/
|
||||
void SetEntry ( DELEGATE < ReturnType, ArgType > aEntry )
|
||||
{
|
||||
m_func = aEntry;
|
||||
}
|
||||
|
||||
/* Function Call()
|
||||
*
|
||||
* Starts execution of a coroutine, passing args as its arguments.
|
||||
* @return true, if the coroutine has yielded and false if it has finished its
|
||||
* execution (returned).
|
||||
*/
|
||||
bool Call( ArgType args )
|
||||
{
|
||||
// fixme: Clean up stack stuff. Add a guard
|
||||
m_stack = malloc(c_defaultStackSize);
|
||||
|
||||
// align to 16 bytes
|
||||
void *sp = (void *) ((((ptrdiff_t) m_stack) + m_stackSize - 0xf) & 0xfffffff0);
|
||||
|
||||
m_args = &args;
|
||||
m_self = boost::context::make_fcontext(sp, m_stackSize, callerStub );
|
||||
m_saved = new boost::context::fcontext_t();
|
||||
|
||||
m_running = true;
|
||||
// off we go!
|
||||
boost::context::jump_fcontext(m_saved, m_self, reinterpret_cast<intptr_t> (this));
|
||||
return m_running;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Resume()
|
||||
*
|
||||
* Resumes execution of a previously yielded coroutine.
|
||||
* @return true, if the coroutine has yielded again and false if it has finished its
|
||||
* execution (returned).
|
||||
*/
|
||||
bool Resume( )
|
||||
{
|
||||
jump_fcontext(m_saved, m_self, 0);
|
||||
return m_running;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ReturnValue()
|
||||
*
|
||||
* Returns the yielded value (the argument Yield() was called with)
|
||||
*/
|
||||
const ReturnType& ReturnValue() const
|
||||
{
|
||||
return m_retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Running()
|
||||
*
|
||||
* @return true, if the coroutine is active
|
||||
*/
|
||||
bool Running() const
|
||||
{
|
||||
return m_running;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static const int c_defaultStackSize = 2000000;
|
||||
|
||||
/* real entry point of the coroutine */
|
||||
static void callerStub(intptr_t data)
|
||||
{
|
||||
// get pointer to self
|
||||
COROUTINE<ReturnType, ArgType> *cor = reinterpret_cast<COROUTINE<ReturnType, ArgType> *> (data);
|
||||
|
||||
// call the coroutine method
|
||||
cor->m_retVal = cor->m_func(*cor->m_args);
|
||||
cor->m_running = false;
|
||||
|
||||
// go back to wherever we came from.
|
||||
boost::context::jump_fcontext(cor->m_self, cor->m_saved, 0); //reinterpret_cast<intptr_t> (this));
|
||||
}
|
||||
|
||||
template <typename T> struct strip_ref {
|
||||
typedef T result;
|
||||
};
|
||||
|
||||
template <typename T> struct strip_ref<T&> {
|
||||
typedef T result;
|
||||
};
|
||||
|
||||
|
||||
DELEGATE < ReturnType, ArgType > m_func;
|
||||
|
||||
///< pointer to coroutine entry arguments. Stripped of references
|
||||
///< to avoid compiler errors.
|
||||
typename strip_ref<ArgType>::result *m_args;
|
||||
ReturnType m_retVal;
|
||||
|
||||
///< saved caller context
|
||||
boost::context::fcontext_t *m_saved;
|
||||
|
||||
///< saved coroutine context
|
||||
boost::context::fcontext_t *m_self;
|
||||
|
||||
///< coroutine stack
|
||||
void *m_stack;
|
||||
|
||||
size_t m_stackSize;
|
||||
|
||||
bool m_running;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __DELEGATE_H
|
||||
#define __DELEGATE_H
|
||||
|
||||
|
||||
/**
|
||||
* class DELEGATE
|
||||
* A trivial delegate (pointer to member method of an object) pattern implementation.
|
||||
* Check delegate_example.cpp for a coding sample.
|
||||
*/
|
||||
|
||||
template<class ReturnType, class Arg>
|
||||
class DELEGATE {
|
||||
public:
|
||||
typedef ReturnType (DELEGATE<ReturnType, Arg>::*MemberPointer)( Arg );
|
||||
typedef ReturnType _ReturnType;
|
||||
typedef Arg _ArgType;
|
||||
|
||||
DELEGATE ()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
DELEGATE ( T* object, ReturnType (T::*ptr)( Arg ) )
|
||||
{
|
||||
m_ptr = reinterpret_cast<MemberPointer>(ptr);
|
||||
m_object = reinterpret_cast<void *> (object);
|
||||
};
|
||||
|
||||
|
||||
ReturnType operator()( Arg a ) const
|
||||
{
|
||||
DELEGATE<ReturnType, Arg> *casted = reinterpret_cast<DELEGATE<ReturnType, Arg> * >(m_object);
|
||||
return (casted->*m_ptr)(a);
|
||||
}
|
||||
|
||||
private:
|
||||
MemberPointer m_ptr;
|
||||
void *m_object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class DELEGATE0
|
||||
* Same as DELEGATE, but with no arguments.
|
||||
*/
|
||||
template<class ReturnType>
|
||||
class DELEGATE0 {
|
||||
public:
|
||||
typedef ReturnType (DELEGATE0<ReturnType>::*MemberPointer)( );
|
||||
|
||||
typedef ReturnType _ReturnType;
|
||||
|
||||
DELEGATE0 ()
|
||||
{
|
||||
}
|
||||
|
||||
template<class T>
|
||||
DELEGATE0 ( T* object, ReturnType (T::*ptr)( ) )
|
||||
{
|
||||
m_ptr = reinterpret_cast<MemberPointer>(ptr);
|
||||
m_object = reinterpret_cast<void *> (object);
|
||||
};
|
||||
|
||||
|
||||
ReturnType operator()( ) const
|
||||
{
|
||||
DELEGATE0<ReturnType> *casted = reinterpret_cast<DELEGATE0<ReturnType> * >(m_object);
|
||||
return (casted->*m_ptr)();
|
||||
}
|
||||
|
||||
private:
|
||||
MemberPointer m_ptr;
|
||||
void *m_object;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __TOOL_BASE_H
|
||||
#define __TOOL_BASE_H
|
||||
|
||||
#include <cassert>
|
||||
|
||||
// for KICAD_T.
|
||||
#include <base_struct.h>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/delegate.h>
|
||||
|
||||
class EDA_ITEM;
|
||||
class TOOL_MANAGER;
|
||||
|
||||
namespace KiGfx {
|
||||
class VIEW;
|
||||
class VIEW_CONTROLS;
|
||||
};
|
||||
|
||||
|
||||
enum TOOL_Type {
|
||||
TOOL_Interactive = 0x1,
|
||||
TOOL_Batch = 0x2
|
||||
};
|
||||
|
||||
typedef int TOOL_ID;
|
||||
typedef DELEGATE<int, TOOL_EVENT&> TOOL_STATE_FUNC;
|
||||
|
||||
/**
|
||||
* Class TOOL_BASE
|
||||
*
|
||||
* Base abstract interface for all kinds of tools
|
||||
*/
|
||||
|
||||
class TOOL_BASE
|
||||
{
|
||||
public:
|
||||
|
||||
TOOL_BASE(TOOL_Type aType, TOOL_ID aId, const std::string& aName = std::string("")) :
|
||||
m_type(aType),
|
||||
m_toolId(aId),
|
||||
m_toolName(aName) {};
|
||||
|
||||
virtual ~TOOL_BASE() {};
|
||||
|
||||
TOOL_Type GetType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
TOOL_ID GetId() const
|
||||
{
|
||||
return m_toolId;
|
||||
}
|
||||
|
||||
const std::string& GetName() const
|
||||
{
|
||||
return m_toolName;
|
||||
}
|
||||
|
||||
TOOL_MANAGER *GetManager()
|
||||
{
|
||||
return m_toolMgr;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend class TOOL_MANAGER;
|
||||
|
||||
/**
|
||||
* Function attachManager()
|
||||
*
|
||||
* Sets the TOOL_MANAGER the tool will belong to.
|
||||
* Called by TOOL_MANAGER::RegisterTool()
|
||||
*/
|
||||
void attachManager( TOOL_MANAGER *aManager );
|
||||
|
||||
KiGfx::VIEW *getView();
|
||||
KiGfx::VIEW_CONTROLS *getViewControls();
|
||||
|
||||
/**
|
||||
* Function getEditFrame()
|
||||
*
|
||||
* Returns the application window object, casted to requested user type, possibly with
|
||||
* run-time type check
|
||||
*/
|
||||
template<typename T>
|
||||
T *getEditFrame()
|
||||
{
|
||||
return static_cast<T*> (getEditFrameInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Function getModel()
|
||||
*
|
||||
* Returns the model object if it matches the requested type.
|
||||
*/
|
||||
template<typename T>
|
||||
T* getModel( KICAD_T modelType )
|
||||
{
|
||||
EDA_ITEM *m = getModelInt();
|
||||
// assert(modelType == m->Type());
|
||||
return static_cast<T*> (m);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
TOOL_Type m_type;
|
||||
TOOL_ID m_toolId;
|
||||
std::string m_toolName;
|
||||
TOOL_MANAGER *m_toolMgr;
|
||||
|
||||
private:
|
||||
|
||||
// hide the implementation to avoid spreading half of
|
||||
// kicad and wxWidgets headers to the tools that may not need them at all!
|
||||
EDA_ITEM *getModelInt();
|
||||
wxWindow *getEditFrameInt();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __TOOL_DISPATCHER_H
|
||||
#define __TOOL_DISPATCHER_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
class TOOL_MANAGER;
|
||||
class PCB_BASE_FRAME;
|
||||
|
||||
namespace KiGfx {
|
||||
class VIEW ;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class TOOL_DISPATCHER
|
||||
*
|
||||
* - takes wx events,
|
||||
* - fixes all wx quirks (mouse warping, etc)
|
||||
* - translates coordinates to world space
|
||||
* - low-level input conditioning (drag/click threshold), updating mouse position during view auto-scroll/pan.
|
||||
* - issues TOOL_EVENTS to the manager
|
||||
*/
|
||||
|
||||
class TOOL_DISPATCHER
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param aToolMgr: tool manager instance the events will be sent to
|
||||
* @param aEditFrame: the frame wx events come from
|
||||
*/
|
||||
TOOL_DISPATCHER( TOOL_MANAGER *aToolMgr, PCB_BASE_FRAME *aEditFrame );
|
||||
~TOOL_DISPATCHER();
|
||||
|
||||
virtual void ResetState ();
|
||||
virtual void DispatchWxEvent(wxEvent &aEvent);
|
||||
virtual void DispatchWxCommand(wxCommandEvent &aEvent);
|
||||
|
||||
private:
|
||||
|
||||
static const int MouseButtonCount = 3;
|
||||
static const int DragTimeThreshold = 300;
|
||||
static const int DragDistanceThreshold = 8;
|
||||
|
||||
bool handleMouseButton ( wxEvent& aEvent, int aIndex, bool aMotion );
|
||||
bool handleKeys ( wxEvent& aEvent );
|
||||
bool handlePopupMenu ( wxEvent& aEvent );
|
||||
|
||||
int decodeModifiers( wxEvent& aEvent );
|
||||
|
||||
KiGfx::VIEW *getView();
|
||||
|
||||
struct ButtonState;
|
||||
|
||||
TOOL_MANAGER *m_toolMgr;
|
||||
PCB_BASE_FRAME *m_editFrame;
|
||||
VECTOR2D m_lastMousePos;
|
||||
std::vector<ButtonState*> m_buttons;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __TOOL_EVENT_H
|
||||
#define __TOOL_EVENT_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <deque>
|
||||
|
||||
#include <math/vector2d.h>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
class TOOL_MANAGER;
|
||||
|
||||
/**
|
||||
* Internal (GUI-independent) event definitions.
|
||||
* Enums are mostly self-explanatory.
|
||||
*/
|
||||
enum TOOL_EventCategory {
|
||||
TC_None = 0x0,
|
||||
TC_Mouse = 0x1,
|
||||
TC_Command = 0x2,
|
||||
TC_Message = 0x4,
|
||||
TC_View = 0x8,
|
||||
TC_Any = 0xffffffff
|
||||
};
|
||||
|
||||
enum TOOL_Actions {
|
||||
TA_None = 0x0,
|
||||
TA_MouseClick = 0x1,
|
||||
TA_MouseUp = 0x2,
|
||||
TA_MouseDown = 0x4,
|
||||
TA_MouseDrag = 0x8,
|
||||
TA_MouseMotion = 0x10,
|
||||
TA_MouseWheel = 0x20,
|
||||
TA_Mouse = 0x3f,
|
||||
TA_ViewRefresh = 0x40,
|
||||
TA_ViewZoom = 0x80,
|
||||
TA_ViewPan = 0x100,
|
||||
TA_ViewDirty = 0x200,
|
||||
TA_ChangeLayer = 0x1000,
|
||||
|
||||
// Tool cancel event. Issued automagically when the user hits escape or selects End Tool from the context menu.
|
||||
TA_CancelTool = 0x2000,
|
||||
|
||||
// Tool activation event. Issued by the GUI upon pressing a button/menu selection.
|
||||
TA_ActivateTool = 0x4000,
|
||||
|
||||
// Context menu update. Issued whenever context menu is open and the user hovers the mouse over one of choices.
|
||||
// Used in dynamic highligting in disambiguation menu
|
||||
TA_ContextMenuUpdate = 0x8000,
|
||||
|
||||
// Context menu choice. Sent if the user picked something from the context menu or closed it without selecting anything.
|
||||
TA_ContextMenuChoice = 0x10000,
|
||||
TA_Any = 0xffffffff
|
||||
};
|
||||
|
||||
enum TOOL_MouseButtons {
|
||||
MB_None = 0x0,
|
||||
MB_Left = 0x1,
|
||||
MB_Right = 0x2,
|
||||
MB_Middle = 0x4,
|
||||
MB_ButtonMask = MB_Left | MB_Right | MB_Middle,
|
||||
MB_ModShift = 0x8,
|
||||
MB_ModCtrl = 0x10,
|
||||
MB_ModAlt = 0x20,
|
||||
MB_ModifierMask = MB_ModShift | MB_ModCtrl | MB_ModAlt,
|
||||
MB_Any = 0xffffffff
|
||||
};
|
||||
|
||||
|
||||
// Defines when a context menu is opened.
|
||||
enum TOOL_ContextMenuTrigger {
|
||||
CMENU_BUTTON = 0, // On the right button
|
||||
CMENU_NOW, // Right now (after TOOL_INTERACTIVE::SetContxtMenu)
|
||||
CMENU_OFF // Never
|
||||
};
|
||||
|
||||
/**
|
||||
* Class TOOL_EVENT
|
||||
*
|
||||
* Generic, UI-independent tool event.
|
||||
*/
|
||||
class TOOL_EVENT
|
||||
{
|
||||
public:
|
||||
|
||||
const std::string Format ( ) const;
|
||||
|
||||
TOOL_EVENT(TOOL_EventCategory aCategory = TC_None, TOOL_Actions aAction = TA_None ):
|
||||
m_category (aCategory),
|
||||
m_actions (aAction),
|
||||
m_mouseButtons(0) {};
|
||||
|
||||
TOOL_EVENT(TOOL_EventCategory aCategory, TOOL_Actions aAction, int aExtraParam ):
|
||||
m_category (aCategory),
|
||||
m_actions (aAction)
|
||||
{
|
||||
if(aCategory == TC_Mouse)
|
||||
m_mouseButtons = aExtraParam;
|
||||
else if (aCategory == TC_Command)
|
||||
m_commandId = aExtraParam;
|
||||
};
|
||||
|
||||
TOOL_EVENT(TOOL_EventCategory aCategory, TOOL_Actions aAction, const std::string& aExtraParam ):
|
||||
m_category (aCategory),
|
||||
m_actions (aAction),
|
||||
m_mouseButtons(0)
|
||||
{
|
||||
if(aCategory == TC_Command)
|
||||
m_commandStr = aExtraParam;
|
||||
}
|
||||
|
||||
|
||||
TOOL_EventCategory Category ( ) const
|
||||
{
|
||||
return m_category;
|
||||
}
|
||||
|
||||
TOOL_Actions Action ( ) const
|
||||
{
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
const VECTOR2D Delta() const
|
||||
{
|
||||
return m_mouseDelta;
|
||||
}
|
||||
|
||||
const VECTOR2D& Position() const
|
||||
{
|
||||
return m_mousePos;
|
||||
}
|
||||
|
||||
const VECTOR2D& DragOrigin() const
|
||||
{
|
||||
return m_mouseDragOrigin;
|
||||
}
|
||||
|
||||
int Buttons() const
|
||||
{
|
||||
return m_mouseButtons;
|
||||
}
|
||||
|
||||
bool IsClick ( int aButtonMask = MB_Any ) const
|
||||
{
|
||||
return (m_actions == TA_MouseClick) && ((m_mouseButtons & aButtonMask) == aButtonMask);
|
||||
}
|
||||
|
||||
bool IsDrag ( int aButtonMask = MB_Any ) const
|
||||
{
|
||||
return (m_actions == TA_MouseDrag) && ((m_mouseButtons & aButtonMask) == aButtonMask);
|
||||
}
|
||||
|
||||
bool IsMouseUp ( int aButtonMask = MB_Any ) const
|
||||
{
|
||||
return (m_actions == TA_MouseUp) && ((m_mouseButtons & aButtonMask) == aButtonMask);
|
||||
}
|
||||
|
||||
bool IsMotion ( ) const
|
||||
{
|
||||
return (m_actions == TA_MouseMotion);
|
||||
}
|
||||
|
||||
bool IsCancel ( ) const
|
||||
{
|
||||
return m_actions == TA_CancelTool;
|
||||
}
|
||||
|
||||
bool Modifier ( int aMask = MB_ModifierMask ) const
|
||||
{
|
||||
return (m_mouseButtons & aMask);
|
||||
}
|
||||
|
||||
|
||||
void Ignore();
|
||||
|
||||
void SetMouseDragOrigin( const VECTOR2D &aP )
|
||||
{
|
||||
m_mouseDragOrigin = aP;
|
||||
}
|
||||
|
||||
void SetMousePosition( const VECTOR2D& aP )
|
||||
{
|
||||
m_mousePos = aP;
|
||||
}
|
||||
|
||||
void SetMouseDelta( const VECTOR2D& aP )
|
||||
{
|
||||
m_mouseDelta = aP;
|
||||
}
|
||||
|
||||
bool Matches ( const TOOL_EVENT& aEvent ) const
|
||||
{
|
||||
if (! (m_category & aEvent.m_category))
|
||||
return false;
|
||||
|
||||
if (! (m_actions & aEvent.m_actions))
|
||||
return false;
|
||||
|
||||
if( m_category == TC_Command)
|
||||
{
|
||||
if(m_commandStr && aEvent.m_commandStr)
|
||||
return (*m_commandStr == *aEvent.m_commandStr);
|
||||
if(m_commandId && aEvent.m_commandId)
|
||||
return (*m_commandId == *aEvent.m_commandId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::optional<int> GetCommandId()
|
||||
{
|
||||
return m_commandId;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
friend class TOOL_MANAGER;
|
||||
|
||||
TOOL_EventCategory m_category;
|
||||
TOOL_Actions m_actions;
|
||||
|
||||
VECTOR2D m_mouseDelta;
|
||||
VECTOR2D m_mousePos;
|
||||
VECTOR2D m_mouseDragOrigin;
|
||||
|
||||
int m_mouseButtons;
|
||||
boost::optional<int> m_commandId;
|
||||
boost::optional<std::string> m_commandStr;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef boost::optional<TOOL_EVENT> OPT_TOOL_EVENT;
|
||||
|
||||
/**
|
||||
* Class TOOL_EVENT_LIST
|
||||
*
|
||||
* A list of TOOL_EVENTs, with overloaded || operators allowing for
|
||||
* concatenating TOOL_EVENTs with little code.
|
||||
*/
|
||||
class TOOL_EVENT_LIST {
|
||||
|
||||
public:
|
||||
typedef TOOL_EVENT value_type;
|
||||
typedef std::deque<TOOL_EVENT>::iterator iterator;
|
||||
typedef std::deque<TOOL_EVENT>::const_iterator const_iterator;
|
||||
|
||||
TOOL_EVENT_LIST() {};
|
||||
TOOL_EVENT_LIST( const TOOL_EVENT& aSingleEvent )
|
||||
{
|
||||
m_events.push_back(aSingleEvent);
|
||||
}
|
||||
|
||||
const std::string Format ( ) const;
|
||||
|
||||
boost::optional<const TOOL_EVENT&> Matches( const TOOL_EVENT &b ) const
|
||||
{
|
||||
for(const_iterator i = m_events.begin(); i != m_events.end(); ++i)
|
||||
if (i->Matches(b))
|
||||
return *i;
|
||||
return boost::optional<const TOOL_EVENT&> ();
|
||||
}
|
||||
|
||||
void Add ( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
m_events.push_back(aEvent);
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return m_events.begin();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return m_events.end();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return m_events.begin();
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return m_events.end();
|
||||
}
|
||||
|
||||
int size() const
|
||||
{
|
||||
return m_events.size();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_events.clear();
|
||||
}
|
||||
|
||||
TOOL_EVENT_LIST& operator=(const TOOL_EVENT_LIST& b)
|
||||
{
|
||||
m_events.clear();
|
||||
for(std::deque<TOOL_EVENT>::const_iterator i = b.m_events.begin(); i != b.m_events.end(); ++i)
|
||||
m_events.push_back(*i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOOL_EVENT_LIST& operator=(const TOOL_EVENT& b)
|
||||
{
|
||||
m_events.clear();
|
||||
m_events.push_back(b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOOL_EVENT_LIST& operator||(const TOOL_EVENT& b)
|
||||
{
|
||||
Add(b);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TOOL_EVENT_LIST& operator||(const TOOL_EVENT_LIST& b)
|
||||
{
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::deque<TOOL_EVENT> m_events;
|
||||
};
|
||||
|
||||
inline const TOOL_EVENT_LIST operator || (const TOOL_EVENT& a, const TOOL_EVENT &b )
|
||||
{
|
||||
TOOL_EVENT_LIST l;
|
||||
|
||||
l.Add(a);
|
||||
l.Add(b);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
inline const TOOL_EVENT_LIST operator || (const TOOL_EVENT & a, const TOOL_EVENT_LIST &b )
|
||||
{
|
||||
TOOL_EVENT_LIST l(b);
|
||||
|
||||
l.Add(a);
|
||||
return l;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __TOOL_INTERACTIVE_H
|
||||
#define __TOOL_INTERACTIVE_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_base.h>
|
||||
|
||||
class CONTEXT_MENU;
|
||||
|
||||
class TOOL_INTERACTIVE : public TOOL_BASE {
|
||||
public:
|
||||
|
||||
TOOL_INTERACTIVE( TOOL_ID aId, const std::string& aName );
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Creates a tool with given name. The name must be unique. */
|
||||
TOOL_INTERACTIVE( const std::string& aName );
|
||||
virtual ~TOOL_INTERACTIVE();
|
||||
|
||||
/**
|
||||
* Function Reset()
|
||||
* Brings the tool to a known, initial state. If the tool claimed anything from the model or the view,
|
||||
* it must release it when its reset.
|
||||
*/
|
||||
virtual void Reset ( ) = 0;
|
||||
|
||||
/**
|
||||
* Function SetContextMenu()
|
||||
*
|
||||
* Assigns a context menu and tells when it should be activated
|
||||
*/
|
||||
void SetContextMenu( CONTEXT_MENU *aMenu, TOOL_ContextMenuTrigger aTrigger = CMENU_BUTTON );
|
||||
|
||||
/**
|
||||
* Function Go()
|
||||
*
|
||||
* Defines which state (aStateFunc) to go when a certain event arrives (aConditions).
|
||||
* No conditions means any event.
|
||||
*/
|
||||
template<class T>
|
||||
void Go ( int (T::*aStateFunc)( TOOL_EVENT& ), const TOOL_EVENT_LIST & aConditions = TOOL_EVENT( TC_Any, TA_Any ) );
|
||||
|
||||
/**
|
||||
* Function Wait()
|
||||
*
|
||||
* Suspends execution of the tool until an event specified in aEventList arrives.
|
||||
* No parameters means waiting for any event.
|
||||
*/
|
||||
OPT_TOOL_EVENT Wait ( const TOOL_EVENT_LIST & aEventList = TOOL_EVENT ( TC_Any, TA_Any ) );
|
||||
|
||||
|
||||
/** functions below are not yet implemented - their interface may change */
|
||||
template<class Parameters, class ReturnValue>
|
||||
bool InvokeTool ( const std::string& aToolName, const Parameters& parameters, ReturnValue& returnValue );
|
||||
|
||||
template<class Parameters, class ReturnValue>
|
||||
bool InvokeWindow ( const std::string& aWindowName, const Parameters& parameters, ReturnValue& returnValue );
|
||||
|
||||
template<class T>
|
||||
void Yield ( const T& returnValue );
|
||||
|
||||
protected:
|
||||
|
||||
/* helper functions for constructing events for Wait() and Go() with
|
||||
less typing */
|
||||
const TOOL_EVENT evActivate( std::string aToolName = "" );
|
||||
const TOOL_EVENT evCommand( int aCommandId = -1 );
|
||||
const TOOL_EVENT evCommand( std::string aCommandStr = "");
|
||||
const TOOL_EVENT evMotion();
|
||||
const TOOL_EVENT evClick(int aButton = MB_Any );
|
||||
const TOOL_EVENT evDrag(int aButton = MB_Any );
|
||||
const TOOL_EVENT evButtonUp( int aButton = MB_Any );
|
||||
const TOOL_EVENT evButtonDown(int aButton = MB_Any );
|
||||
|
||||
private:
|
||||
|
||||
void goInternal( TOOL_STATE_FUNC& aState, const TOOL_EVENT_LIST& aConditions );
|
||||
};
|
||||
|
||||
// hide TOOL_MANAGER implementation
|
||||
template<class T>
|
||||
void TOOL_INTERACTIVE::Go( int (T::*aStateFunc)( TOOL_EVENT& ), const TOOL_EVENT_LIST& aConditions )
|
||||
{
|
||||
TOOL_STATE_FUNC sptr (static_cast<T*>(this), aStateFunc);
|
||||
goInternal( sptr, aConditions );
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
|
||||
*
|
||||
* 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 2
|
||||
* 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, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __TOOL_MANAGER_H
|
||||
#define __TOOL_MANAGER_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include <math/vector2d.h>
|
||||
|
||||
#include <tool/tool_event.h>
|
||||
#include <tool/tool_base.h>
|
||||
|
||||
class TOOL_BASE;
|
||||
class CONTEXT_MENU;
|
||||
class wxWindow;
|
||||
|
||||
/**
|
||||
* Class TOOL_MANAGER.
|
||||
* Master controller class:
|
||||
* - registers editing tools
|
||||
* - pumps UI events to tools requesting them
|
||||
* - manages tool state machines (transitions and wait requests)
|
||||
*/
|
||||
class TOOL_MANAGER
|
||||
{
|
||||
public:
|
||||
|
||||
TOOL_MANAGER();
|
||||
~TOOL_MANAGER();
|
||||
|
||||
/**
|
||||
* Generates an unique ID from for a tool with given name.
|
||||
*/
|
||||
static TOOL_ID MakeToolId( const std::string &aToolName );
|
||||
|
||||
/**
|
||||
* Function RegisterTool()
|
||||
* Adds a tool to the manager set and sets it up. Called once for
|
||||
* each tool during application initialization.
|
||||
* @param aTool: tool to be added. Ownership is transferred.
|
||||
*/
|
||||
void RegisterTool(TOOL_BASE *aTool);
|
||||
|
||||
/**
|
||||
* Function InvokeTool()
|
||||
* Calls a tool by sending a tool activation event to tool of given ID or name.
|
||||
* An user-defined parameter object can be also passed
|
||||
*/
|
||||
void InvokeTool(TOOL_ID aToolId);
|
||||
void InvokeTool(const std::string& name);
|
||||
|
||||
template <class Parameters>
|
||||
void InvokeTool( const std::string& name, const Parameters& aToolParams);
|
||||
|
||||
|
||||
/**
|
||||
* Function FindTool()
|
||||
* Searches for a tool with given name or ID
|
||||
*/
|
||||
TOOL_BASE *FindTool(int aId);
|
||||
TOOL_BASE *FindTool(const std::string& aName);
|
||||
|
||||
/**
|
||||
* Resets the state of a given tool by clearing its wait and
|
||||
* transition lists and calling tool's internal Reset() method.
|
||||
*/
|
||||
|
||||
void ResetTool( TOOL_BASE *aTool );
|
||||
|
||||
/**
|
||||
* Takes an event from the TOOL_DISPATCHER and propagates it to
|
||||
* tools that requested events of matching type(s)
|
||||
*/
|
||||
bool ProcessEvent (TOOL_EVENT& aEvent);
|
||||
|
||||
/**
|
||||
* Sets the work environment (model, view, view controls and the parent window).
|
||||
* These are made available to the tool. Called by the parent frame (PCB_EDIT_FRAME)
|
||||
* when the board is set up
|
||||
*/
|
||||
void SetEnvironment( EDA_ITEM *aModel, KiGfx::VIEW* aView, KiGfx::VIEW_CONTROLS *aViewControls, wxWindow *aFrame );
|
||||
|
||||
/* Accessors for the environment objects (view, model, etc.) */
|
||||
KiGfx::VIEW* GetView()
|
||||
{
|
||||
return m_view;
|
||||
}
|
||||
|
||||
KiGfx::VIEW_CONTROLS* GetViewControls()
|
||||
{
|
||||
return m_viewControls;
|
||||
}
|
||||
|
||||
EDA_ITEM* GetModel()
|
||||
{
|
||||
return m_model;
|
||||
}
|
||||
|
||||
wxWindow* GetEditFrame()
|
||||
{
|
||||
return m_editFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a state transition - the events that cause a given handler method in the tool
|
||||
* to be called. Called by TOOL_INTERACTIVE::Go(). May be called from a coroutine context.
|
||||
*/
|
||||
void ScheduleNextState( TOOL_BASE *aTool, TOOL_STATE_FUNC& aHandler, const TOOL_EVENT_LIST & aConditions );
|
||||
|
||||
/**
|
||||
* Pauses execution of a given tool until one or more events matching aConditions arrives. The pause/resume
|
||||
* operation is done through COROUTINE object. Called only from coroutines.
|
||||
*/
|
||||
boost::optional<TOOL_EVENT> ScheduleWait( TOOL_BASE *aTool, const TOOL_EVENT_LIST & aConditions );
|
||||
|
||||
/**
|
||||
* Sets behaviour of the tool's context popup menu.
|
||||
* @param aMenu - the menu structure, defined by the tool
|
||||
* @param aTrigger - when the menu is activated:
|
||||
* CMENU_NOW: opens the menu right now
|
||||
* CMENU_BUTTON: opens the menu when RMB is pressed
|
||||
* CMENU_OFF: menu is disabled.
|
||||
* May be called from a coroutine context.
|
||||
*/
|
||||
void ScheduleContextMenu( TOOL_BASE *aTool, CONTEXT_MENU *aMenu, TOOL_ContextMenuTrigger aTrigger );
|
||||
|
||||
private:
|
||||
|
||||
void dispatchInternal ( TOOL_EVENT& aEvent );
|
||||
|
||||
struct ToolState;
|
||||
typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> Transition;
|
||||
|
||||
std::map<TOOL_BASE*, ToolState*> m_toolState;
|
||||
std::map<std::string, ToolState*> m_toolNameIndex;
|
||||
std::map<TOOL_ID, ToolState*> m_toolIdIndex;
|
||||
|
||||
EDA_ITEM *m_model;
|
||||
KiGfx::VIEW *m_view;
|
||||
KiGfx::VIEW_CONTROLS *m_viewControls;
|
||||
wxWindow *m_editFrame;
|
||||
|
||||
ToolState *m_currentTool;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue