#include <gtk/gtk.h>
#include <X11/Xlib.h>
#include <mil.h>
#include "MdispGtk.h"
#include <gdk/gdkx.h>
#include "childframe.h"
#include "mdispgtkview.h"
#include "mainframe.h"
#include "mdispgtkmarshal.h"
gint ChildFrame::SignalId = 0;
ChildFrame::ChildFrame(MainFrame* mf):m_mf(mf)
{
m_View = NULL;
m_FrameStr[0] ='\0';
m_ScaleStr[0] ='\0';
m_MouseStr[0] ='\0';
GtkWidget* vbox = NULL;
SignalId++;
m_frameRateChangedSignalName = g_strdup_printf("frame-rate-changed-%d", SignalId);
m_zoomFactorChangedSignalName = g_strdup_printf("zoom-factor-changed-%d",SignalId);
m_mousePositionChangedSignalName = g_strdup_printf("mouse-position-changed-%d",SignalId);
m_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
m_frameRateChangedSignal = g_signal_new(m_frameRateChangedSignalName,
G_TYPE_OBJECT,
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
mdispgtk_marshal_VOID__DOUBLE,
G_TYPE_NONE,
1,
G_TYPE_DOUBLE);
m_zoomFactorChangedSignal = g_signal_new(m_zoomFactorChangedSignalName,
G_TYPE_OBJECT,
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
mdispgtk_marshal_VOID__DOUBLE_DOUBLE,
G_TYPE_NONE,
2,
G_TYPE_DOUBLE,
G_TYPE_DOUBLE);
m_mousePositionChangedSignal = g_signal_new(m_mousePositionChangedSignalName,
G_TYPE_OBJECT,
G_SIGNAL_RUN_LAST,
0,
NULL,
NULL,
mdispgtk_marshal_VOID__INT_INT_DOUBLE_DOUBLE,
G_TYPE_NONE,
4,
G_TYPE_INT,
G_TYPE_INT,
G_TYPE_DOUBLE,
G_TYPE_DOUBLE);
vbox = gtk_vbox_new (false, 0);
gtk_container_add (GTK_CONTAINER (m_window), vbox);
m_DrawingArea = gtk_drawing_area_new ();
gtk_container_add (GTK_CONTAINER (vbox), m_DrawingArea);
GtkWidget* mainWindow = m_mf->MainWindow();
MdispGtkApp* App = (MdispGtkApp *) g_object_get_data(G_OBJECT(mainWindow),"App");
g_object_set_data(G_OBJECT(m_DrawingArea),"App",(void *) App);
g_object_set_data(G_OBJECT(m_DrawingArea),"MainWindow",(void *) mainWindow);
m_View = new MdispGtkView(this);
gtk_window_set_title(GTK_WINDOW(m_window), m_View->filename());
m_StatusBar = gtk_statusbar_new ();
gtk_box_pack_end (GTK_BOX (vbox), m_StatusBar, false, false, 0);
gtk_widget_set_events (m_DrawingArea, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
gtk_widget_set_double_buffered(m_DrawingArea,FALSE);
gtk_widget_set_events(m_DrawingArea,0);
g_signal_connect (G_OBJECT (m_window), "focus-in-event", G_CALLBACK (ChildFrame::OnChildGetFocus),this);
g_signal_connect (G_OBJECT (m_window), "delete-event", G_CALLBACK (ChildFrame::OnChildDelete),this);
g_signal_connect (G_OBJECT (m_window), "destroy", G_CALLBACK (ChildFrame::OnChildDestroy),this);
g_signal_connect (G_OBJECT (m_DrawingArea), "configure-event", G_CALLBACK (ChildFrame::OnChildConfigure),this);
g_signal_connect (G_OBJECT (m_DrawingArea), "expose-event", G_CALLBACK (ChildFrame::OnChildExpose),this);
g_signal_connect (G_OBJECT (m_window), m_frameRateChangedSignalName, G_CALLBACK (ChildFrame::OnFrameRateChanged),this);
g_signal_connect (G_OBJECT (m_window), m_zoomFactorChangedSignalName, G_CALLBACK (ChildFrame::OnZoomFactorChanged),this);
g_signal_connect (G_OBJECT (m_window), m_mousePositionChangedSignalName, G_CALLBACK (ChildFrame::OnMousePositionChanged),this);
gtk_widget_show_all(m_window);
gdk_display_flush(gdk_display_get_default());
m_mf->setcf(this);
UpdateStatusBarWithFrameRate(0.0);
UpdateStatusBarWithScale(1.0, 1.0);
UpdateStatusBarWithMousePosition(0,0,0.0,0.0);
m_layout = gtk_widget_create_pango_layout(m_DrawingArea,NULL);
}
ChildFrame::~ChildFrame()
{
if(m_View) delete m_View;
g_free(m_frameRateChangedSignalName);
g_free(m_zoomFactorChangedSignalName);
g_free(m_mousePositionChangedSignalName);
}
MdispGtkView* ChildFrame::View()
{
return m_View;
}
void ChildFrame::close()
{
gtk_widget_destroy(m_window);
}
void ChildFrame::setTitle(const gchar* title)
{
if(title)
gtk_window_set_title(GTK_WINDOW(m_window),title);
}
void ChildFrame::show()
{
gtk_widget_show_all(m_window);
}
void ChildFrame::OnChildDestroy(GtkWidget *widget, gpointer user_data)
{
ChildFrame* cf = (ChildFrame *) user_data;
g_return_if_fail(cf);
cf->OnChildDelete(widget,NULL, user_data);
}
gboolean ChildFrame::OnChildDelete(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
ChildFrame* cf = (ChildFrame *) user_data;
g_return_val_if_fail(cf, false);
MainFrame* mf = cf->m_mf;
gint result;
if(cf->View() && cf->View()->IsModified())
{
GtkWidget *dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
" MdispGtk Save Image ?");
gtk_window_set_title(GTK_WINDOW(dialog),"MdispGtk Message");
result = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
switch(result)
{
case GTK_RESPONSE_YES:
mf->fileSaveAs(NULL,mf);
break;
case GTK_RESPONSE_NO:
break;
}
}
if(mf)
{
mf->remove(cf);
}
if(cf->m_View) delete cf->m_View;
cf->m_View = NULL;
return false;
}
gboolean ChildFrame::OnChildGetFocus(GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
{
ChildFrame* cf = (ChildFrame *) user_data;
g_return_val_if_fail(cf, true);
MainFrame* mf = cf->m_mf;
g_return_val_if_fail(mf, true);
mf->setcf(cf);
return true;
}
gboolean ChildFrame::OnChildConfigure(GtkWidget *widget, GdkEventConfigure *event, gpointer user_data)
{
return true;
}
gboolean ChildFrame::OnChildExpose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
ChildFrame* cf = (ChildFrame *) user_data;
g_return_val_if_fail(cf, true);
cf->m_View->Paint();
return true;
}
void ChildFrame::UpdateStatusBar()
{
if(GTK_WIDGET_VISIBLE(m_window))
{
gchar *text = g_strdup_printf("%s | %s %s",
m_FrameStr,
m_ScaleStr,
m_MouseStr);
gtk_statusbar_push (GTK_STATUSBAR(m_StatusBar), 0, text);
g_free(text);
}
}
void ChildFrame::UpdateStatusBarWithFrameRate(MIL_DOUBLE CurrentRate)
{
if(CurrentRate == M_INVALID)
{
g_snprintf(m_FrameStr,STRING_SIZE,"%s","Display Updates Not Available");
}
else
{
g_snprintf(m_FrameStr,STRING_SIZE,"Display Updates :%.2f fps",CurrentRate);
}
UpdateStatusBar();
}
void ChildFrame::UpdateStatusBarWithScale(MIL_DOUBLE CurrentScaleX, MIL_DOUBLE CurrentScaleY)
{
g_snprintf(m_ScaleStr,STRING_SIZE,"%.4f, %.4f",CurrentScaleX, CurrentScaleY );
UpdateStatusBar();
}
void ChildFrame::UpdateStatusBarWithMousePosition(long DispX, long DispY, double BufX, double BufY)
{
g_snprintf(m_MouseStr,STRING_SIZE,"M:(%d,%d)->(%.2f,%.2f)",(gint)DispX, (gint)DispY, BufX, BufY);
UpdateStatusBar();
}
void ChildFrame::UpdateContentSize(long SizeX, long SizeY)
{
long NewSizeX = SizeX;
long NewSizeY = SizeY;
if(GTK_WIDGET_VISIBLE(m_window))
{
NewSizeY+= m_StatusBar->allocation.height;
gdk_window_resize(m_window->window,NewSizeX,NewSizeY);
}
}
void ChildFrame::OnFrameRateChanged(GtkWidget *widget, gdouble Rate, gpointer user_data)
{
ChildFrame* cf = (ChildFrame *) user_data;
g_return_if_fail(cf);
cf->UpdateStatusBarWithFrameRate(Rate);
}
void ChildFrame::OnZoomFactorChanged(GtkWidget *widget, gdouble ScaleX, gdouble ScaleY, gpointer user_data)
{
ChildFrame* cf = (ChildFrame *) user_data;
g_return_if_fail(cf);
cf->UpdateStatusBarWithScale(ScaleX, ScaleY);
}
void ChildFrame::OnMousePositionChanged(GtkWidget *widget, gint DispX, gint DispY, gdouble BufX, gdouble BufY, gpointer user_data)
{
ChildFrame* cf = (ChildFrame *) user_data;
g_return_if_fail(cf);
cf->UpdateStatusBarWithMousePosition(DispX, DispY, BufX, BufY);
}