Logo Search packages:      
Sourcecode: vertex version File versions

vmastatusbar.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <gtk/gtk.h>

#include "guiutils.h"

#include "editor.h"
#include "editorcb.h"
#include "editorlightcb.h"
#include "texbrowser.h"

#include "vmastatusbar.h"
#include "msglist.h"
#include "messages.h"
#include "vmacfg.h"
#include "vmacfglist.h"
#include "vma.h"
#include "config.h"

#ifdef MEMWATCH
# include "memwatch.h"
#endif


#include "images/icon_secure_16x16.xpm"
#include "images/icon_insecure_16x16.xpm"
#include "images/icon_backup_16x16.xpm"
#include "images/icon_backup_disabled_16x16.xpm"
#include "images/icon_vma_16x16.xpm"
#include "images/icon_mp_color_16x16.xpm"
#include "images/icon_lighting_16x16.xpm"
#include "images/icon_texture_16x16.xpm"
#include "images/icon_scratchpad_16x16.xpm"


static gint VMAStatusBarButtonEventCB(
      GtkWidget *widget, GdkEventButton *button, gpointer data
);
vma_status_bar_struct *VMAStatusBarNew(
        void *core_ptr, void *editor_ptr, GtkWidget *parent 
);
void VMAStatusBarUpdateMenus(vma_status_bar_struct *sb);
void VMAStatusBarDelete(vma_status_bar_struct *sb);

void VMAStatusBarCursorPosition(
        vma_status_bar_struct *sb, double x, double y, double z
);
void VMAStatusBarMessage(vma_status_bar_struct *sb, const char *mesg);
void VMAStatusBarProgress(vma_status_bar_struct *sb, double percent);


#define VMA_STATUS_BAR_HEIGHT 26


/*
 *    Status bar button event callback (for the event boxes holding
 *    the write protect and automatic backup state icons).
 */
static gint VMAStatusBarButtonEventCB(
        GtkWidget *widget, GdkEventButton *button, gpointer data
)
{
      GtkWidget *w = widget;
        vma_status_bar_struct *sb = (vma_status_bar_struct *)data;
      if((w == NULL) || (sb == NULL))
          return(FALSE);

      if(w == sb->write_protect_enabled_eb)
      {
          EditorWriteProtectDisableCB(w, sb->editor_ptr);
      }
      else if(w == sb->write_protect_disabled_eb)
      {
            EditorWriteProtectEnableCB(w, sb->editor_ptr);
      }
      else if((w == sb->backup_enabled_eb) ||
                (w == sb->backup_disabled_eb)
      )
      {
          EditorBackupPreferencesCB(w, sb->editor_ptr);
      }

      return(TRUE);
}

/*
 *    Creates a new status bar.
 *
 *    Given parent is assumed to be a GtkBox.
 */
vma_status_bar_struct *VMAStatusBarNew(
      void *core_ptr, void *editor_ptr, GtkWidget *parent
)
{
      const char *msglist[] = VMA_MSGLIST_EDITOR_SB_TOOLTIPS;
        GtkWidget *w, *parent2, *parent3;
        GtkAdjustment *adj;
      vma_status_bar_struct *sb = (vma_status_bar_struct *)calloc(
          1, sizeof(vma_status_bar_struct)
      );
      if(sb == NULL)
          return(NULL);

      sb->initialized = TRUE;
      sb->write_protect = FALSE;
      sb->core_ptr = core_ptr;
      sb->editor_ptr = editor_ptr;

        /* Main frame. */
        sb->toplevel = w = gtk_frame_new(NULL);
        gtk_widget_set_usize(w, -1, VMA_STATUS_BAR_HEIGHT);
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_OUT);
        gtk_container_border_width(GTK_CONTAINER(w), 0);
        gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
        gtk_widget_show(w);
        parent2 = w;

        /* Table in main frame. */
        w = gtk_table_new(1, 6, FALSE);
        gtk_container_add(GTK_CONTAINER(parent2), w);
        gtk_widget_show(w);
        parent2 = w;


      /* Write protect enabled/disabled. */
      /* Write protect enabled. */
      sb->write_protect_enabled_eb = w = gtk_event_box_new();
        gtk_widget_add_events(w, GDK_BUTTON_PRESS_MASK);
        gtk_signal_connect(
            GTK_OBJECT(w), "button_press_event",
            GTK_SIGNAL_FUNC(VMAStatusBarButtonEventCB),
            (gpointer)sb
        );
      gtk_table_attach(
            GTK_TABLE(parent2), w,
            0, 1, 0, 1,
            0, 0,
            2, 0
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_WRITE_PROTECT_ENABLED
            )
        );
      parent3 = w;
      /* Do not show write protect enabled. */

      w = GUICreateMenuItemIcon(
          (u_int8_t **)icon_secure_16x16_xpm
      );
      gtk_container_add(GTK_CONTAINER(parent3), w);
      gtk_widget_set_usize(w, 16, 16);
      gtk_widget_show(w);


      /* Write protect disabled. */
        sb->write_protect_disabled_eb = w = gtk_event_box_new();
        gtk_widget_add_events(w, GDK_BUTTON_PRESS_MASK);
        gtk_signal_connect(
            GTK_OBJECT(w), "button_press_event",
            GTK_SIGNAL_FUNC(VMAStatusBarButtonEventCB),
            (gpointer)sb
        );
        gtk_table_attach(
            GTK_TABLE(parent2), w,
            0, 1, 0, 1,
            0, 0,
            2, 0
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_WRITE_PROTECT_DISABLED
            )
        );
        gtk_widget_show(w);
      parent3 = w;

      w = GUICreateMenuItemIcon(
            (u_int8_t **)icon_insecure_16x16_xpm
        );
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_set_usize(w, 16, 16);
        gtk_widget_show(w);


      /* Automatic backup enabled/disabled. */
      /* Automatic backup enabled. */
        sb->backup_enabled_eb = w = gtk_event_box_new();
        gtk_widget_add_events(w, GDK_BUTTON_PRESS_MASK);
        gtk_signal_connect(
            GTK_OBJECT(w), "button_press_event",
            GTK_SIGNAL_FUNC(VMAStatusBarButtonEventCB),
            (gpointer)sb
        );
        gtk_table_attach(
            GTK_TABLE(parent2), w,
            1, 2, 0, 1,
            0, 0,
            2, 0
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_AUTO_BACKUP_ENABLED
            )
        );   
        /* Do not show backup enabled. */
      parent3 = w;

      w = GUICreateMenuItemIcon(
            (u_int8_t **)icon_backup_16x16_xpm
        );
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_set_usize(w, 16, 16);
        gtk_widget_show(w);


      /* Automatic backup disabled. */
        sb->backup_disabled_eb = w = gtk_event_box_new();
      gtk_widget_add_events(w, GDK_BUTTON_PRESS_MASK);
      gtk_signal_connect(
          GTK_OBJECT(w), "button_press_event",
          GTK_SIGNAL_FUNC(VMAStatusBarButtonEventCB),
          (gpointer)sb
      );
        gtk_table_attach(
            GTK_TABLE(parent2), w,
            1, 2, 0, 1,
            0, 0,
            2, 0
        );  
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_AUTO_BACKUP_DISABLED
            )
        );
        gtk_widget_show(w);
        parent3 = w;

        w = GUICreateMenuItemIcon(
            (u_int8_t **)icon_backup_disabled_16x16_xpm
        );
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_set_usize(w, 16, 16);
        gtk_widget_show(w);


        /* Progress bar. */
        adj = (GtkAdjustment *)gtk_adjustment_new(0, 1, 100, 0, 0, 0);
        sb->progress_bar = w = gtk_progress_bar_new_with_adjustment(adj);
        gtk_widget_set_usize(w, 100, 20);
        gtk_progress_bar_set_orientation(
            GTK_PROGRESS_BAR(w), GTK_PROGRESS_LEFT_TO_RIGHT
        );
        gtk_progress_bar_set_bar_style(
            GTK_PROGRESS_BAR(w), GTK_PROGRESS_CONTINUOUS
        );
        gtk_progress_set_activity_mode(
            GTK_PROGRESS(w), FALSE
        );
        gtk_table_attach(
            GTK_TABLE(parent2), w,
            2, 3, 0, 1,
            0,
            GTK_FILL,
            0, 0
        );
        gtk_widget_show(w);

        /* Label. */
        w = gtk_frame_new(NULL);
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
        gtk_container_border_width(GTK_CONTAINER(w), 1);
        gtk_table_attach(
            GTK_TABLE(parent2), w,
            3, 4, 0, 1,
            GTK_SHRINK | GTK_EXPAND | GTK_FILL,
            GTK_FILL,
            0, 0
        );
        gtk_widget_show(w);
        parent3 = w;

        w = gtk_hbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_show(w);
        parent3 = w;

        sb->label = w = gtk_label_new("");
        gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);

        /* Cursor position label. */
        w = gtk_frame_new(NULL);  
        gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
        gtk_container_border_width(GTK_CONTAINER(w), 1);
        gtk_table_attach(  
            GTK_TABLE(parent2), w,
            4, 5, 0, 1,
            GTK_SHRINK | GTK_FILL,
            GTK_FILL,
            0, 0
        );
        gtk_widget_show(w);
        parent3 = w;

        w = gtk_hbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_show(w);
        parent3 = w;

        sb->cursor_position = w = gtk_label_new("");
        gtk_widget_set_usize(w, 170, -1);
        gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 2);
        gtk_widget_show(w);


        /* Handle bar for window map buttons. */
        w = gtk_handle_box_new();
        gtk_table_attach(
            GTK_TABLE(parent2), w,
            5, 6, 0, 1,
            GTK_SHRINK | GTK_FILL,
            GTK_SHRINK | GTK_FILL,
            0, 0
        );
        gtk_widget_show(w);
        parent3 = w;

        /* Hbox for window map buttons. */
        w = gtk_hbox_new(FALSE, 0);
        gtk_container_add(GTK_CONTAINER(parent3), w);
        gtk_widget_show(w);
        parent3 = w;

        /* Window map buttons. */
      /* New editor. */
        sb->new_editor_btn = w = (GtkWidget *)GUIButtonPixmap(
            (u_int8_t **)icon_vma_16x16_xpm
        );
        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_set_usize(w, 25, -1);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(VMANewEditorCB),
            (gpointer)core_ptr
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_NEW_EDITOR
            )
        );
        gtk_widget_show(w);

      /* Color selector. */
        sb->color_selector_btn = w = (GtkWidget *)GUIButtonPixmap(  
            (u_int8_t **)icon_mp_color_16x16_xpm
        );
        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);   
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_set_usize(w, 25, -1);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorMapClrSelCB),
            (gpointer)editor_ptr
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_COLOR_SELECTOR
            )
        );
        gtk_widget_show(w);

        /* Light properties. */
        sb->light_properties_btn = w = (GtkWidget *)GUIButtonPixmap(
            (u_int8_t **)icon_lighting_16x16_xpm
        );
        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_set_usize(w, 25, -1);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorLightPropertiesCB),
            (gpointer)editor_ptr
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_LIGHT_PROPERTIES
            )
        );
        gtk_widget_show(w);

        /* Texture browser. */
        sb->texture_browser_btn = w = (GtkWidget *)GUIButtonPixmap(  
            (u_int8_t **)icon_texture_16x16_xpm
        );
        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);   
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_set_usize(w, 25, -1);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(EditorMapTextureBrowserCB),
            (gpointer)editor_ptr
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_TEXTURE_BROWSER
            )
        );
        gtk_widget_show(w);

        /* Scratchpad. */
        sb->scratchpad_btn = w = (GtkWidget *)GUIButtonPixmap(
            (u_int8_t **)icon_scratchpad_16x16_xpm
        );
        gtk_button_set_relief(GTK_BUTTON(w), GTK_RELIEF_NONE);
        gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
        gtk_widget_set_usize(w, 25, -1);
        gtk_signal_connect(
            GTK_OBJECT(w), "clicked",
            GTK_SIGNAL_FUNC(VMAScratchPadMapCB),
            (gpointer)core_ptr
        );
        GUISetWidgetTip(
            w,
            MsgListMatchCaseMessage(
                msglist,
                VMA_MSGNAME_EDITOR_SB_SCRATCHPAD
            )
        );
        gtk_widget_show(w);


      return(sb);
}

/*
 *    Updates menus and related resources on the status bar.
 */
void VMAStatusBarUpdateMenus(vma_status_bar_struct *sb)
{
      GtkWidget *w;
      vma_core_struct *core_ptr;
      ma_editor_struct *editor;


      if(sb == NULL)
          return;

      /* Get editor if valid. */
      editor = (ma_editor_struct *)sb->editor_ptr;
      if(editor != NULL)
      {
          /* Update write protect display. */
          w = sb->write_protect_enabled_eb;
          if(w != NULL)
          {
            if(editor->write_protect)
                gtk_widget_show(w);
            else
                gtk_widget_hide(w);
          }

            w = sb->write_protect_disabled_eb;
            if(w != NULL)
            {
                if(editor->write_protect)
                    gtk_widget_hide(w);
                else
                    gtk_widget_show(w);
            }
      }

      /* Get core structure if valid. */
      core_ptr = (vma_core_struct *)sb->core_ptr;
      if(core_ptr != NULL)
      {
          w = sb->backup_enabled_eb;
          if(w != NULL)
          {
            if(core_ptr->backup_toid == (guint)(-1))
                gtk_widget_hide(w);
            else
                gtk_widget_show(w);
          }

            w = sb->backup_disabled_eb;
            if(w != NULL)
            {
                if(core_ptr->backup_toid == (guint)(-1))
                    gtk_widget_show(w);
                else
                    gtk_widget_hide(w);
            }

      }

      return;
}

/*
 *    Destroys the given status bar.
 */
void VMAStatusBarDelete(vma_status_bar_struct *sb)
{
      GtkWidget **w;


      if(sb == NULL)
          return;

      if(sb->initialized)
      {
#define DO_DESTROY_WIDGET       \
{ \
 if((*w) != NULL) \
 { \
  GtkWidget *tmp_w = *w; \
  (*w) = NULL; \
  gtk_widget_destroy(tmp_w); \
 } \
}
          /* Begin destroying widgets. */
          w = &sb->progress_bar;
          DO_DESTROY_WIDGET

          w = &sb->cursor_position;
          DO_DESTROY_WIDGET

          w = &sb->label;
          DO_DESTROY_WIDGET

          w = &sb->toplevel;
          DO_DESTROY_WIDGET

#undef DO_DESTROY_WIDGET
      }

      /* Deallocate structure itself. */
      free(sb);
}


/*
 *    Updates the cursor position label on the status bar.
 */
void VMAStatusBarCursorPosition(
      vma_status_bar_struct *sb, double x, double y, double z
)
{
        GtkWidget *w;
      int decimals;
      char fmt_str[40];
        char num_str[3 * 40];

        if(sb == NULL)
            return;

        w = sb->cursor_position;
        if(w == NULL)
            return;

      decimals = VMACFGItemListGetValueI(
          option, VMA_CFG_PARM_VIEW_DECIMALS_POSITION
      );

      sprintf(
          fmt_str,
          "%%.%if %%.%if %%.%if",
          decimals, decimals, decimals
      );
      sprintf(num_str, fmt_str, x, y, z);
        gtk_label_set_text(GTK_LABEL(w), num_str);

        /* Itterate through GTK main function until all events are handled
         * so that we ensure this label text is updated.
         */
        while(gtk_events_pending() > 0)
            gtk_main_iteration();

        return;
}

/*
 *    Updates the message on the status bar.
 */
void VMAStatusBarMessage(vma_status_bar_struct *sb, const char *mesg)
{
        GtkWidget *w;

      if(sb == NULL)
          return;

        w = sb->label;
        if(w == NULL)
            return;

        gtk_label_set_text(
            GTK_LABEL(w),
            (mesg == NULL) ? "" : mesg
        );

        /* Itterate through GTK main function until all events are handled
         * so that we ensure this label text is updated.
         */
        while(gtk_events_pending() > 0)
            gtk_main_iteration();

      return;
}

/*
 *    Updates the progress on the status bar.
 */
void VMAStatusBarProgress(vma_status_bar_struct *sb, double percent)
{
        GtkWidget *w;
        gfloat p;

        if(sb == NULL)
            return;

        w = sb->progress_bar;
        if(w == NULL)
            return;

      p = (gfloat)percent;

        /* Negative? Implies just do activity. */
        if(p < 0.0)
        {
            GtkAdjustment *adj = GTK_PROGRESS(w)->adjustment;

            p = gtk_progress_get_value(GTK_PROGRESS(w)) + 1;
            if(p > adj->upper)
                p = adj->lower;

            gtk_progress_set_activity_mode(
                GTK_PROGRESS(w), TRUE
            );
            gtk_progress_set_show_text(
                GTK_PROGRESS(w), FALSE
            );
            gtk_progress_set_value(GTK_PROGRESS(w), p);

            /* Itterate through GTK main function until all events are
             * handled so that we ensure this progress bar setting is
             * updated.
             */
            while(gtk_events_pending() > 0)
                gtk_main_iteration();

            return;
        }

      /* Sanitize percent. */
        if(p > 1.0)
            p = 1.0;

      /* Reset last progress position if it is greater than the
       * given position.
       */
      if(sb->progress_pos_last > p)
          sb->progress_pos_last = -1.0;

      /* Check if percent did not sufficiently change (use 0.01
       * increments).
       */
      if((p - sb->progress_pos_last) < 0.01)
          return;

      /* Update progress. */
        gtk_progress_set_activity_mode(
            GTK_PROGRESS(w), FALSE
        );
        gtk_progress_set_format_string(
            GTK_PROGRESS(w), "%p%%"
        );
        gtk_progress_set_show_text(
            GTK_PROGRESS(w), (p > 0) ? TRUE : FALSE
        );
      gtk_progress_bar_update(
          GTK_PROGRESS_BAR(w), p
      );
      /* Itterate through GTK main function until all events are
       * handled so that we ensure this progress bar setting is
       * updated.
       */
      while(gtk_events_pending() > 0)
          gtk_main_iteration();

      /* Record last position. */
      sb->progress_pos_last = p;

        return;
}

Generated by  Doxygen 1.6.0   Back to index