' ProgressBar.bas
' Translated from C to FB by TinyCla, 2006
'
' Reviewed by TJF (2011-2014)
' Details: http://developer.gnome.org/gtk/

#INCLUDE ONCE "Gir/Gtk-3.0.bi"
'#INCLUDE ONCE "Gir/Gtk-2.0.bi"
#INCLUDE ONCE "Gir/_GObjectMacros-2.0.bi"

TYPE ProgressData
  AS GtkWidget PTR win, pbar, infbut
#IF GTK_MAJOR_VERSION > 2
  AS GtkWidget PTR perbut
#ENDIF
  AS guint pb_timer = 100
  AS gboolean activity_mode
END TYPE

' Update the value of the progress bar so that we get
' some movement
FUNCTION progress_timeout CDECL( BYVAL user_data AS gpointer ) AS gboolean

  VAR pdata = CAST(ProgressData PTR, user_data)
  VAR pbar = GTK_PROGRESS_BAR (pdata->pbar)

  IF  pdata->activity_mode THEN
    gtk_progress_bar_pulse (pbar)
  ELSE
    ' Calculate the value of the progress bar using the
    ' value range set in the adjustment object
    VAR new_val = gtk_progress_bar_get_fraction (pbar) + 0.01
    IF new_val > 1.0 THEN new_val = 0.0
    ' Set the new value
    gtk_progress_bar_set_fraction (pbar, new_val)
  END IF

  ' As this is a timeout function, return TRUE so that it
  ' continues to get called
  RETURN TRUE

END FUNCTION

' Callback that toggles the text display within the progress bar trough
SUB toggle_show_text CDECL( BYVAL widget AS GtkWidget PTR, BYVAL pdata AS ProgressData PTR)

  VAR pbar = GTK_PROGRESS_BAR (pdata->pbar)

#IF GTK_MAJOR_VERSION > 2
  VAR show = IIF(gtk_progress_bar_get_show_text (pbar), 0, 1)
  gtk_progress_bar_set_show_text (pbar, show)
  gtk_widget_set_sensitive(pdata->perbut, show)
#ELSE
  VAR text = gtk_progress_bar_get_text (pbar)
  IF text THEN
    gtk_progress_bar_set_text (pbar, NULL)
  ELSE
    gtk_progress_bar_set_text (pbar, "some text")
  END IF
#ENDIF

END SUB

#IF GTK_MAJOR_VERSION > 2
' Callback that toggles the text display within the progress bar trough
SUB toggle_show_percentage CDECL( BYVAL widget AS GtkWidget  PTR, BYVAL pdata AS ProgressData PTR)

  VAR pbar = GTK_PROGRESS_BAR (pdata->pbar)

  VAR text = gtk_progress_bar_get_text (pbar)
  IF text THEN
    gtk_progress_bar_set_text (pbar, NULL)
  ELSE
    gtk_progress_bar_set_text (pbar, "some text")
  END IF

END SUB
#ENDIF

' Callback that toggles the activity mode of the progress bar
SUB toggle_activity_mode CDECL( BYVAL widget AS GtkWidget PTR, BYVAL pdata AS ProgressData PTR )

  pdata->activity_mode = NOT pdata->activity_mode
  IF pdata->activity_mode THEN
    gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar))
    gtk_widget_set_sensitive(pdata->infbut, FALSE)
  ELSE
    gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), 0.0)
    gtk_widget_set_sensitive(pdata->infbut, TRUE)
  END IF

END SUB

' Callback that toggles the orientation of the progress bar
SUB toggle_orientation CDECL( BYVAL widget AS GtkWidget PTR, BYVAL pdata AS ProgressData PTR)

  VAR pbar = GTK_PROGRESS_BAR (pdata->pbar)

#IF GTK_MAJOR_VERSION > 2
  VAR ori = IIF(gtk_progress_bar_get_inverted (pbar), 0, 1)
  gtk_progress_bar_set_inverted (pbar, ori)
#ELSE
  SELECT CASE AS CONST gtk_progress_bar_get_orientation (pbar)
  CASE GTK_PROGRESS_LEFT_TO_RIGHT:
    gtk_progress_bar_set_orientation (pbar,  GTK_PROGRESS_RIGHT_TO_LEFT)
  CASE GTK_PROGRESS_RIGHT_TO_LEFT:
    gtk_progress_bar_set_orientation (pbar, GTK_PROGRESS_LEFT_TO_RIGHT)
  CASE ELSE
  END SELECT
#ENDIF

END SUB



' ==============================================
' Main
' ==============================================

' Initialize the toolkit
gtk_init(@__FB_ARGC__, @__FB_ARGV__)

' Create the data that is passed to the callbacks
VAR pdata = NEW ProgressData

pdata->win = gtk_window_new (GTK_WINDOW_TOPLEVEL)
gtk_window_set_resizable (GTK_WINDOW (pdata->win), TRUE)

g_signal_connect (G_OBJECT (pdata->win), "delete-event", _
                  G_CALLBACK (@gtk_main_quit), pdata)
gtk_window_set_title (GTK_WINDOW (pdata->win), "GtkProgressBar")
gtk_container_set_border_width (GTK_CONTAINER (pdata->win), 0)

VAR vbox = gtk_vbox_new (FALSE, 5)
gtk_container_set_border_width (GTK_CONTAINER (vbox), 10)
gtk_container_add (GTK_CONTAINER (pdata->win), vbox)
gtk_widget_show (vbox)

' Create a centering alignment object
VAR align = gtk_alignment_new (0.5, 0.5, 0, 0)
gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 5)
gtk_widget_show (align)

' Create the GtkProgressBar
pdata->pbar = gtk_progress_bar_new ()
gtk_container_add (GTK_CONTAINER (align), pdata->pbar)
#IF GTK_MAJOR_VERSION > 2
gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(pdata->pbar), TRUE)
gtk_progress_bar_set_text (GTK_PROGRESS_BAR(pdata->pbar), "some text")
gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR(pdata->pbar), FALSE)
#ENDIF
gtk_widget_show (pdata->pbar)

' Add a timer callback to update the value of the progress bar
pdata->pb_timer = g_timeout_add (pdata->pb_timer, @progress_timeout, pdata)

VAR separator = gtk_hseparator_new ()
gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 5)
gtk_widget_show (separator)

' Add a check button to select displaying of the trough text
VAR check = gtk_check_button_new_with_label ("Show text")
gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0)
g_signal_connect (G_OBJECT (check), "clicked", G_CALLBACK (@toggle_show_text), pdata)
gtk_widget_show (check)

#IF GTK_MAJOR_VERSION > 2
' Add a check button to select displaying of the percentage
pdata->perbut = gtk_check_button_new_with_label ("Percentage")
gtk_widget_set_sensitive(pdata->perbut, FALSE)
gtk_box_pack_start (GTK_BOX (vbox), pdata->perbut, FALSE, FALSE, 0)
g_signal_connect (G_OBJECT (pdata->perbut), "clicked", _
                  G_CALLBACK (@toggle_show_percentage), pdata)
gtk_widget_show (pdata->perbut)
#ENDIF

' Add a check button to toggle activity mode
check = gtk_check_button_new_with_label ("Activity mode")
gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0)
g_signal_connect (G_OBJECT (check), "clicked", _
                  G_CALLBACK (@toggle_activity_mode), pdata)
gtk_widget_show (check)

' Add a check button to toggle orientation
pdata->infbut = gtk_check_button_new_with_label ("Inverted")
gtk_box_pack_start (GTK_BOX (vbox), pdata->infbut, FALSE, FALSE, 0)
g_signal_connect (G_OBJECT (pdata->infbut), "clicked", _
                  G_CALLBACK (@toggle_orientation), pdata)
gtk_widget_show (pdata->infbut)

separator = gtk_hseparator_new ()
gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 5)
gtk_widget_show (separator)

' Add a button to exit the program
VAR button = gtk_button_new_with_label ("close")
g_signal_connect_swapped (G_OBJECT (button), "clicked", _
                          G_CALLBACK (@gtk_main_quit), pdata)
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0)

' This makes it so the button is the default.
gtk_widget_set_can_default (button, TRUE)

' This grabs this button to be the default button. Simply hitting
' the "Enter" key will cause this button to activate.
gtk_widget_grab_default (button)
gtk_widget_show (button)

gtk_widget_show (pdata->win)

gtk_main ()

DELETE (pdata)
