/** ******************************************************************************* * @file MenuContext.cpp * @brief Editeur De N'ours : special Menu (left button or normal menu) (Sources) * @author Edouard DUPIN * @date 22/07/2011 * @par Project * Edn * * @par Copyright * Copyright 2010 Edouard DUPIN, all right reserved * * This software is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY. * * Licence summary : * You can modify and redistribute the sources code and binaries. * You can send me the bug-fix * You can not earn money with this Software (if the source extract from Edn * represent less than 50% of original Sources) * Term of the licence in in the file licence.txt. * ******************************************************************************* */ #include "tools_debug.h" #include "tools_globals.h" #include "MenuContext.h" #undef __class__ #define __class__ "MenuContext" /** * @brief * * @param[in,out] --- * * @return --- * */ MenuContext::MenuContext(void) : MsgBroadcast("Menu Context", EDN_CAT_MENU_CONTEXT) { //m_currentBufferID = -1; m_dialog = NULL; m_shawableSize.x=200; m_shawableSize.y=200; // Init link with the buffer Manager m_bufferManager = BufferManager::getInstance(); m_colorManager = ColorizeManager::getInstance(); } /** * @brief * * @param[in,out] --- * * @return --- * */ MenuContext::~MenuContext(void) { if(NULL != m_dialog) { gtk_widget_destroy(m_dialog); m_dialog = NULL; } } void MenuContext::OnMessage(int32_t id, int32_t dataID) { switch (id) { /* case EDN_MSG__BUFFER_CHANGE_CURRENT: m_currentBufferID = dataID; break; */ } } void MenuContext::Clear(void) { } void MenuContext::AddCommonElem(int32_t id) { } void MenuContext::AddSpecificElem(Edn::String &text) { } /* This is called when we need to draw the windows contents */ static gboolean expose (GtkWidget *widget, GdkEventExpose *event, gpointer userdata) { gint width; gint height; cairo_t *cr = NULL; # if USE_GTK_VERSION_3_0 cr = gdk_cairo_create(gtk_widget_get_window(widget)); # elif USE_GTK_VERSION_2_0 cr = gdk_cairo_create(widget->window); # endif //if (supports_alpha) { // transparent cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); } /* else { // opaque white cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); } */ /* draw the background */ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); /* draw a circle */ //gtk_window_get_size (GTK_WINDOW (widget), &width, &height); //cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6); //cairo_arc (cr, width / 2, height / 2, (width < height ? width : height) / 2 - 8 , 0, 2 * 3.14); //cairo_fill (cr); //cairo_stroke (cr); //cairo_paint (cr); cairo_destroy (cr); return FALSE; } // http://zetcode.com/tutorials/cairographicstutorial/transparency/ void MenuContext::Show(int32_t x, int32_t y, bool top) { if(NULL != m_dialog) { gtk_widget_destroy(m_dialog); m_dialog = NULL; } m_dialog = gtk_window_new(GTK_WINDOW_POPUP); //m_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); // Set the dialog on top of the selected windows //gtk_window_set_transient_for(GTK_WINDOW(m_dialog), parent); // unset the border of the windows //gtk_window_set_decorated(GTK_WINDOW(m_dialog), FALSE); EDN_INFO("Set position X=" << x+2 << " Y=" << y+27); # if USE_GTK_VERSION_3_0 gtk_window_move(GTK_WINDOW(m_dialog), x+2, y+27); # elif USE_GTK_VERSION_2_0 gtk_widget_set_uposition(m_dialog, x+2, y+27); # endif #if 0 /* sdsfsdf */ gtk_widget_set_app_paintable (m_dialog, TRUE); # ifdef USE_GTK_VERSION_3_0 g_signal_connect( G_OBJECT(m_dialog), "draw", G_CALLBACK(expose), this); # elif defined( USE_GTK_VERSION_2_0 ) g_signal_connect( G_OBJECT(m_dialog), "expose_event", G_CALLBACK(expose), this); # endif #endif //gtk_window_set_opacity(GTK_WINDOW(m_dialog), 0.25); // enable the close signal of the windows //g_signal_connect(G_OBJECT(m_mainWindow), "delete-event", G_CALLBACK(OnQuit), this); //g_signal_connect(G_OBJECT(m_mainWindow), "destroy", G_CALLBACK(OnQuit), this); /* // Create a vertical box for stacking the menu and editor widgets in. GtkWidget *vbox = gtk_vbox_new (FALSE, 0); gtk_container_add(GTK_CONTAINER(m_dialog), vbox); GtkWidget *myLabel = gtk_label_new("plop 1 "); gtk_container_add(GTK_CONTAINER(vbox), myLabel); myLabel = gtk_label_new("plop 2 "); gtk_container_add(GTK_CONTAINER(vbox), myLabel); */ // Set key Accelerator : //AccelKey::getInstance()->LinkCommonAccel(GTK_WINDOW(m_dialog)); // Create the menu bar. //gtk_box_pack_start( GTK_BOX (vbox), m_MenuBar.GetWidget(), FALSE, FALSE, 0); m_widget = gtk_drawing_area_new(); //gtk_window_set_opacity(GTK_WINDOW(m_widget), 0.8); gtk_widget_set_size_request( m_widget, 250, 100); gtk_widget_add_events( m_widget, GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); # ifdef USE_GTK_VERSION_3_0 g_object_set(m_widget,"can-focus", TRUE, NULL); # elif defined( USE_GTK_VERSION_2_0 ) GTK_WIDGET_SET_FLAGS(m_widget, GTK_CAN_FOCUS); # endif // Focus Event g_signal_connect( G_OBJECT(m_widget), "focus_in_event", G_CALLBACK(CB_focusGet), this); g_signal_connect( G_OBJECT(m_widget), "focus_out_event", G_CALLBACK(CB_focusLost), this); // Keyboard Event g_signal_connect_after( G_OBJECT(m_widget), "key_press_event", G_CALLBACK(CB_keyboardEvent), this); g_signal_connect_after( G_OBJECT(m_widget), "key_release_event", G_CALLBACK(CB_keyboardEvent), this); // Mouse Event g_signal_connect( G_OBJECT(m_widget), "button_press_event", G_CALLBACK(CB_mouseButtonEvent), this); g_signal_connect( G_OBJECT(m_widget), "button_release_event", G_CALLBACK(CB_mouseButtonEvent), this); g_signal_connect( G_OBJECT(m_widget), "motion_notify_event", G_CALLBACK(CB_mouseMotionEvent), this); // Display Event g_signal_connect( G_OBJECT(m_widget), "realize", G_CALLBACK(CB_displayInit), this); # ifdef USE_GTK_VERSION_3_0 g_signal_connect( G_OBJECT(m_widget), "draw", G_CALLBACK(CB_displayDraw), this); # elif defined( USE_GTK_VERSION_2_0 ) g_signal_connect( G_OBJECT(m_widget), "expose_event", G_CALLBACK(CB_displayDraw), this); # endif gtk_container_add(GTK_CONTAINER(m_dialog), m_widget); // recursive version of gtk_widget_show gtk_widget_show_all(m_dialog); // Set the Focus gtk_widget_grab_focus(m_widget); } void MenuContext::Hide(void) { if(NULL != m_dialog) { gtk_widget_destroy(m_dialog); m_dialog = NULL; } } gboolean MenuContext::CB_displayDraw( GtkWidget *widget, GdkEventExpose *event, gpointer data) { MenuContext * self = reinterpret_cast(data); # ifdef USE_GTK_VERSION_3_0 GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); if (self->m_shawableSize.x != allocation.width) { self->m_shawableSize.x = allocation.width; } if (self->m_shawableSize.y != allocation.height) { self->m_shawableSize.y = allocation.height; } # elif defined( USE_GTK_VERSION_2_0) if (self->m_shawableSize.x != widget->allocation.width) { self->m_shawableSize.x = widget->allocation.width; } if (self->m_shawableSize.y != widget->allocation.height) { self->m_shawableSize.y = widget->allocation.height; } # endif EDN_INFO("Request a display of : " << self->m_shawableSize.x << "px * "<< self->m_shawableSize.y<<"px"); DrawerManager monDrawer(widget, self->m_shawableSize.x, self->m_shawableSize.y); // get the number of buffer open int32_t nbBufferOpen = self->m_bufferManager->Size(); int32_t i; uint32_t lineID = 0; uint32_t fontHeight = Display::GetFontHeight(); basicColor_te selectFG = COLOR_LIST_TEXT_NORMAL; basicColor_te selectBG = COLOR_LIST_BG_1; EdnVectorBin myData; Edn::String * plop = new Edn::String("Save"); myData.PushBack(plop); plop = new Edn::String("Show"); myData.PushBack(plop); plop = new Edn::String("Close"); myData.PushBack(plop); for (i=0; i < myData.Size(); i++) { selectFG = COLOR_LIST_TEXT_NORMAL; if (lineID%2==0) { selectBG = COLOR_LIST_BG_1; } else { selectBG = COLOR_LIST_BG_2; } monDrawer.Rectangle(self->m_colorManager->Get(selectBG), 0, lineID*fontHeight, self->m_shawableSize.x, Display::GetFontHeight()); monDrawer.Text(self->m_colorManager->Get(selectFG), 2, lineID*fontHeight, myData[i]->c_str()); monDrawer.Flush(); lineID ++; } return TRUE; } gboolean MenuContext::CB_displayDraw2( GtkWidget *widget, GdkEventExpose *event, gpointer data) { MenuContext * self = reinterpret_cast(data); gint width; gint height; cairo_t *cr = NULL; # if USE_GTK_VERSION_3_0 cr = gdk_cairo_create(gtk_widget_get_window(widget)); # elif USE_GTK_VERSION_2_0 cr = gdk_cairo_create(widget->window); # endif // transparent cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* draw the background */ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_paint (cr); /* draw a circle */ gtk_window_get_size (GTK_WINDOW(widget), &width, &height); cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6); cairo_arc (cr, width / 2, height / 2, (width < height ? width : height) / 2 - 8 , 0, 2 * 3.14); cairo_fill (cr); cairo_stroke (cr); cairo_paint (cr); cairo_destroy (cr); return FALSE; } // sur : émis lors du premier affichage de la GtkDrawingArea gboolean MenuContext::CB_displayInit( GtkWidget *widget, gpointer data) { MenuContext * self = reinterpret_cast(data); # ifdef USE_GTK_VERSION_3_0 GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int32_t size_x = allocation.width; int32_t size_y = allocation.height; self->m_shawableSize.x = allocation.width; self->m_shawableSize.y = allocation.height; # elif defined( USE_GTK_VERSION_2_0) int32_t size_x = widget->allocation.width; int32_t size_y = widget->allocation.height; self->m_shawableSize.x = widget->allocation.width; self->m_shawableSize.y = widget->allocation.height; # endif EDN_INFO("Request a diplay of : " << size_x << "px * " << size_y << "px"); gtk_widget_queue_draw( widget ); return TRUE; } gint MenuContext::CB_focusGet( GtkWidget *widget, GdkEventFocus *event, gpointer data) { //MenuContext * self = reinterpret_cast(data); # ifdef USE_GTK_VERSION_2_0 GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS); # endif EDN_INFO("Focus - In"); gtk_widget_queue_draw( widget ); return FALSE; } gint MenuContext::CB_focusLost( GtkWidget *widget, GdkEventFocus *event, gpointer data) { MenuContext * self = reinterpret_cast(data); # ifdef USE_GTK_VERSION_2_0 GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS); # endif EDN_INFO("Focus - out"); self->Hide(); return FALSE; } gint MenuContext::CB_keyboardEvent( GtkWidget *widget, GdkEventKey *event, gpointer data) { //MenuContext * self = reinterpret_cast(data); if(event->type == GDK_KEY_PRESS) { gtk_widget_queue_draw( widget ); } return true; } gint MenuContext::CB_mouseButtonEvent(GtkWidget *widget, GdkEventButton *event, gpointer data) { MenuContext * self = reinterpret_cast(data); // get focus on the widget gtk_widget_grab_focus(widget); if (event->button == 1) { /* if (event->type == GDK_BUTTON_PRESS) { EDN_INFO("mouse-event BT1 ==> One Clicked"); }else*/ if (event->type == GDK_2BUTTON_PRESS) { //EDN_INFO("mouse-event BT1 ==> Double Clicked %d, %d", (uint32_t)event->x, (uint32_t)event->y); uint32_t fontHeight = Display::GetFontHeight(); int32_t selectBuf = self->m_bufferManager->WitchBuffer((event->y / fontHeight) + 1); //EDN_INFO(" plop %d / %d = %d ==> %d", (uint32_t)event->y, fontHeight, ((uint32_t)event->y / fontHeight), selectBuf); if ( 0 <= selectBuf) { self->SendMessage(EDN_MSG__CURRENT_CHANGE_BUFFER_ID, selectBuf); /* MainWindows *window = MainWindows::getInstance(); EDN_INFO(" Event on Buffer " << selectBuf); // set the new seected Buffer window->SetSelected(selectBuf); */ } }/* else if (event->type == GDK_3BUTTON_PRESS) { EDN_INFO("mouse-event BT1 ==> Triple Clicked"); }else if (event->type == GDK_BUTTON_RELEASE) { EDN_INFO("mouse-event BT1 ==> Realease"); }*/ }/* else if (event->button == 2) { if (event->type == GDK_BUTTON_PRESS) { EDN_INFO("mouse-event BT2 PRESS"); self->m_menuContext->Show(event->x, event->y, false); } } else if (event->button == 3) { if (event->type == GDK_BUTTON_PRESS) { EDN_INFO("mouse-event BT3 PRESS"); uint32_t fontHeight = Display::GetFontHeight(); int32_t selectBuf = self->m_bufferManager->WitchBuffer((event->y / fontHeight) + 1); if ( 0 <= selectBuf) { // TODO : Find a simple methode int32_t windowsPosX, windowsPosY; gtk_window_get_position(GTK_WINDOW(gtk_widget_get_toplevel(widget)), &windowsPosX, &windowsPosY); //EDN_INFO("windowsPosX=" << windowsPosX << " windowsPosY=" << windowsPosY); int32_t widgetPosX, widgetPosY; gtk_widget_translate_coordinates(widget, gtk_widget_get_toplevel(widget), 0, 0, &widgetPosX, &widgetPosY); //EDN_INFO("widgetPosX=" << widgetPosX << " widgetPosY=" << widgetPosY); self->m_menuContext->Show(self->m_shawableAreaX+2+widgetPosX+windowsPosX, ((int32_t)(event->y / fontHeight)*fontHeight)+(fontHeight/2)+widgetPosY+windowsPosY, false); } } }*/ else { EDN_INFO("mouse-event BT? PRESS"); } gtk_widget_queue_draw( widget ); return true; } gint MenuContext::CB_mouseMotionEvent( GtkWidget *widget, GdkEventMotion *event, gpointer data) { //MenuContexterView * self = reinterpret_cast(data); /* if (true == ButtunOneSelected) { int x, y; GdkModifierType state; if (event->is_hint) { gdk_window_get_pointer(event->window, &x, &y, &state); } else { x = event->x; y = event->y; state = (GdkModifierType)event->state; } EDN_INFO("mouse-motion BT1 %d, %d", x, y); } */ return true; }