Lots of reorganization to get the Evolution shell to begin its life. It

Lots of reorganization to get the Evolution shell to begin its life.
It also includes a new evolution widget from Damon.

Miguel.

svn path=/trunk/; revision=1536
This commit is contained in:
Arturo Espinosa
2000-01-06 05:48:27 +00:00
parent 36e5e42d31
commit ed4e8afecd
100 changed files with 8066 additions and 7872 deletions

View File

@ -1,3 +1,15 @@
2000-01-05 Miguel de Icaza <miguel@gnu.org>
* shell/Makefile.am: New file.
* configure.in (EXTRA_GNOME_CFLAGS_THREADS,
EXTRA_GNOME_LIBS_THREADS): New variables that hold the thread
version of the compile/link lines.
1999-11-20 Miguel de Icaza <miguel@gnu.org>
* configure.in (PACKAGE): Raise warning level.
2000-01-04 bertrand <Bertrand.Guiheneuf@aful.org>
* camel/providers/mbox/camel-mbox-folder.c (_list_subfolders):

View File

@ -1,2 +1 @@
Email: Bertrand.Guiheneuf@aful.org
Email: miguel@kernel.org

View File

@ -2,6 +2,8 @@ SUBDIRS = \
po \
macros \
camel \
e-util \
widgets \
composer \
tests

View File

@ -61,6 +61,7 @@ libcamel_la_SOURCES = \
data-wrapper-repository.c \
gmime-base64.c \
gmime-content-field.c \
gmime-rfc2047.c \
gmime-utils.c \
gstring-util.c \
hash-table-utils.c \

View File

@ -24,7 +24,7 @@ AC_CANONICAL_HOST
AM_ACLOCAL_INCLUDE(macros)
GNOME_INIT
GNOME_COMPILE_WARNINGS
AC_ISC_POSIX
AC_PROG_CC
AC_PROG_CPP
@ -84,11 +84,16 @@ else
AC_MSG_ERROR(Did not find libGlade installed)
fi
EXTRA_GNOME_LIBS="`gnome-config --libs gnomeui libglade ` `glib-config --libs gthread`"
EXTRA_GNOME_CFLAGS="`gnome-config --cflags gnomeui libglade ` `glib-config --cflags gthread`"
EXTRA_GNOME_LIBS="`gnome-config --libs gnomeui libglade `"
EXTRA_GNOME_CFLAGS="`gnome-config --cflags gnomeui libglade `"
AC_SUBST(EXTRA_GNOME_LIBS)
AC_SUBST(EXTRA_GNOME_CFLAGS)
EXTRA_GNOME_LIBS_THREADS="`gnome-config --libs gnomeui libglade ` `glib-config --libs gthread`"
EXTRA_GNOME_CFLAGS_THREADS="`gnome-config --cflags gnomeui libglade ` `glib-config --cflags gthread`"
AC_SUBST(EXTRA_GNOME_LIBS_THREADS)
AC_SUBST(EXTRA_GNOME_CFLAGS_THREADS)
AC_ARG_WITH(camel-hard-log-level, [ --with-camel-hard-log-level=level value of log level in camel (0-10)],
camel_hard_log_level="$withval", camel_hard_log_level="0")
@ -98,6 +103,7 @@ AC_OUTPUT([
Makefile
macros/Makefile
po/Makefile.in
e-util/Makefile
camel/Makefile
camel/providers/Makefile
camel/providers/MH/Makefile
@ -110,4 +116,7 @@ tests/Makefile
tests/ui-tests/Makefile
widgets/Makefile
widgets/meeting-time-sel/Makefile
widgets/shortcut-bar/Makefile
widgets/e-table/Makefile
shell/Makefile
])

7
e-util/Makefile.am Normal file
View File

@ -0,0 +1,7 @@
noinst_LIBRARIES = libeutil.a
libeutil_a_SOURCES = \
e-cursors.c \
e-cursors.h \
e-util.h

3
shell/.cvsignore Normal file
View File

@ -0,0 +1,3 @@
Makefile
Makefile.in
evolution

19
shell/Makefile.am Normal file
View File

@ -0,0 +1,19 @@
bin_PROGRAMS = evolution
INCLUDES = \
-DEVOLUTION_VERSION=\""$(VERSION)"\" \
-DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
-DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
-DEVOLUTION_LOCALEDIR=\""$(datadir)/locale"\" \
-I$(srcdir)/../widgets \
$(EXTRA_GNOME_CFLAGS)
evolution_SOURCES = \
main.c
evolution_LDADD = \
-L../widgets/shortcut-bar/libshortcut-bar.a \
$(EXTRA_GNOME_LIBS)

View File

@ -5,7 +5,7 @@ INCLUDES = -I$(top_srcdir)/intl -I$(top_srcdir) -I$(top_srcdir)/camel \
LDADD = \
$(top_builddir)/camel/libcamel.la \
$(GNOME_LIBDIR) \
$(GNOMEUI_LIBS) $(INTLLIBS) $(PTHREAD_LIB) $(EXTRA_GNOME_LIBS)
$(GNOMEUI_LIBS) $(INTLLIBS) $(PTHREAD_LIB) $(EXTRA_GNOME_LIBS_THREADS)
# $(BONOBO_LIBS)
@ -22,5 +22,6 @@ noinst_PROGRAMS = \
test1 \
test2 \
test3 \
test4 test5 test6 \
test7 \
test8

View File

@ -1,579 +0,0 @@
1999-12-30 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_attach_cell_views): New routine, creates the
cell views.
(eti_detach_cell_views): Detaches the cell_views from the
ETableItem.
(eti_realize_cell_views, eti_unrealize_cell_views): Simplified to
just do realize/unrealize notification.
(eti_add_table_model): Only attach the cells when we have both the
table model and the header model.
* e-cell.h (ECellClass): Added two new methods: new_view and
kill_view which drive the view process (instead of putting that on
realize/unrealize).
* e-cell.c: Adapt the code to use the new scheme for view
instantiation.
* e-cell-text.c, e-cell-toggle.c: Adapted to the new class
changes.
1999-12-22 Miguel de Icaza <miguel@helixcode.com>
* e-table-item.c (e_table_item_focus): grab focus here with the
canvas method.
1999-12-20 Miguel de Icaza <miguel@helixcode.com>
* e-table-group.c (etg_update): Change the dimensions only if the
child changes its own.
* e-table-item.c (eti_table_model_changed): Emit new signal on
table height change.
(eti_class_init): Register new "height_change" signal.
1999-12-19 Damon Chaplin <damon@karuna.freeserve.co.uk>
* Makefile.am (SUBDIRS): created SUBDIRS with meeting-time-sel.
* meeting-time-sel/Makefile.am:
* meeting-time-sel/.cvsignore:
* meeting-time-sel/e-meeting-time-sel.h:
* meeting-time-sel/e-meeting-time-sel.c:
* meeting-time-sel/e-meeting-time-sel-item.h:
* meeting-time-sel/e-meeting-time-sel-item.c:
* meeting-time-sel/e-meeting-time-sel-list-item.h:
* meeting-time-sel/e-meeting-time-sel-list-item.c:
* meeting-time-sel/e-meeting-time-sel-mail.xpm:
* meeting-time-sel/e-meeting-time-sel-no-mail.xpm:
* meeting-time-sel/test-meeting-time-sel.c: new files implementing
the meeting time selector.
1999-12-12 Miguel de Icaza <miguel@helixcode.com>
* e-table-item.c (eti_class_init): X and Y arguments are now
doubles (to make it consistent with the rest of the canvas x, y
arguments).
* e-table.c (e_table_create_leaf): Use new argument values here
* test-*.c: Update to new argument types for x and y
* e-table-group.c: New implementation as a canvas item used to
group childs.
* e-table-item.c (eti_update): Make this play nicely with groups.
(eti_draw): ditto.
(eti_request_region_redraw): ditto.
(eti_item_region_redraw): New function.
* e-table-subset.c (etss_proxy_model_row_changed): Added model
proxying.
* e-cell.h: Drop ETableModel from the ECell;
(realize): Now takes an ETableModel
* e-cell-checkbox.c: Adapted to new class
changes;
* e-cell-toggle.c: ditto
* e-table-subset.c (etss_row_count): Fix this guy.
1999-12-11 Miguel de Icaza <miguel@helixcode.com>
* e-table-item.c (eti_unrealize_cell_views): Null the cell views.
(eti_header_structure_changed): Only unrealize/realize if we were
realized before.
* e-table-header.c (e_table_header_add_column): Allow -1 as an
insert position
1999-12-11 Miguel de Icaza <miguel@helixcode.com>
* e-table.c: Massive fixage.
* test-table.c: Updates to test the mega widget.
1999-12-10 Miguel de Icaza <miguel@helixcode.com>
* e-table.c: New file, implements the mega widget.
1999-12-09 Miguel de Icaza <miguel@gnu.org>
* e-table-header.c (e_table_header_col_diff): fix this routine.
1999-12-04 Miguel de Icaza <miguel@gnu.org>
* e-table-header-item.c (ethi_event): Started drag and drop
support.
* e-table-item.c (eti_table_model_changed): The columns are
controled by the Header, not by the TableModel.
* e-table-header-item.c (ethi_draw): Fixed redraw logic to support
arbitrary header positioning.
* e-cell.h: Revamped e-cell interface. We now provide the model
column and the view column to all methods (so that the methods can
talk to the view and to the model at the same time).
* e-table-item.c: Update to new API
* e-cell-test.c: Update to new API
1999-12-03 Miguel de Icaza <miguel@gnu.org>
* e-cell.c (e_cell_class_init): Provide emtpy methods for
enter_edit, and leave_edit.
* e-table-item.c: Killed draw cell.
(eti_draw): Perform column mapping here.
(e_table_item_leave_edit): ditto.
(e_table_item_enter_edit): ditto.
(eti_event): ditto.
1999-12-02 Miguel de Icaza <miguel@gnu.org>
* e-table-header.c (e_table_header_index): fixed api.
1999-12-01 Miguel de Icaza <miguel@gnu.org>
* test-cols.c (multi_cols_test): Update to simplified API.
* test-check.c (check_test): ditto
* test-table.c (table_browser_test): ditto
* e-table-simple.c (e_table_simple_class_init): Kill column_name method.
* e-table-model.h: Kill column_name method.
* e-table-col.c (e_table_col_new): Instead of using a column name,
use a column index.
* e-cell-text.c (ect_draw): Keep track of the originally allocated
piece of code.
* e-table-header-item.c (ethi_unrealize): Removed change cursor
from here.
* e-cell-text.c (ect_draw): Memory leak fix.
* table-test.c (main): Enhance the demo to load sample.table
automatically, to get memprof working.
* e-table-header.c (eth_do_remove): Take an argument: do -remove.
* e-table-header.c (e_table_header_add_column): Sink ETableCol to
own the object.
* e-table-col.h: Made ETableCol a GtkObject to make reference
counting the lifecycle method for these objects.
* e-table-col.c (e_table_col_destroy): New API call.
* e-table-subset.c (e_table_subset_get_toplevel): New API call.
1999-11-30 Miguel de Icaza <miguel@gnu.org>
* e-cell-checkbox.c (e_cell_checkbox_new): This one derives from
e-cell-toggle.
* check-emtpy.xpm, check-filled.xpm: new files.
* e-cell-toggle.c (etog_draw): Paint in white.
If we have transparency enabled, do the nice alpha computation.
* test-table.c, test-cols.c: new files; They implement the split
tests.
1999-11-29 Miguel de Icaza <miguel@gnu.org>
* e-table-col.c (e_table_col_new): Set etc->resizeable.
* e-table-header-item.c (ethi_event): Handle non-resizeables
columns; Add support for minimum width.
* e-cell-toggle.c, e-cell-toggle.h: New file. Implement a
multi-state image toggle cell object.
* e-cell-text.c (ect_leave_edit): Handle the case of us calling
leave edit manually.
(ect_stop_editing): Leave manually editing here.
(ect_draw): Add one pixel to the border for left and right;
Handle off-screen cursor (must be improved).
(ect_edit_select_all): New function.
(ect_event): Select all text on editing start
* e-table-item.c (eti_event): Map mouse events and dispatch them.
(eti_event): Add spreadsheet mode for editing; Enter editing only
with visual characters;
Leave editing mode when a different row has been selected.
(eti_get_height): Fix the computation for this; Fix logic for the
length_threshold.
(eti_draw): Add borders on all sides of the box;
Only draw focus if the cell is not being edited.
1999-11-28 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_draw): Focus inside, not outside.
(eti_realize): Enhance our focus gc.
* e-cell-text.c (ect_enter_edit, ect_leave_edit): New methods;
They implement editing.
* e-cell.h: new methods: enter_edit, leave_edit
* e-table-model.h (set_value_at): make val argument const.
* e-table-simple.c (simple_set_value_at): Make value argument const;
* e-table-item.c (eti_set_arg): Add new mode: draw_focus;
1999-11-27 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_event): beginning of the keyboard navigation.
* e-table-model.c (e_table_model_row_changed): new function.
(e_table_model_cell_changed): new function.
(e_table_model_class_init): New signals.
* e-table-item.c (eti_request_region_redraw): x2, y2 offsets were
wrong.
(eti_select): Repaint selected region.
(eti_request_region_redraw): Fix range.
(eti_draw): Correct offset computation here.
(e_table_item_class_init): New method: row_selection, handles the
selection.
Now it implement GTK_SELECTION_SINGLE and GTK_SELECTION_MULTIPLE.
Focusing and selection should be correct now.
1999-11-26 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_realize): Compute height using the ecell
methods here.
(eti_get_height): new method to compute dimensions.
* e-cursors.c: use a different cursor.
* e-table-model.h: kill height and row_height methods.
* e-cell.c (ec_height): New method.
* e-cell-text.c (ect_realize): Load the font from the canvas.
(ect_draw): New color setup.
Center in the row.
(ect_height): Implement new method.
1999-11-26 Michael Meeks <mmeeks@gnu.org>
* ROADMAP.e-table: small spelling/typo fixes.
1999-11-25 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_event): Work on mouse-button event
propagation to cells.
* e-cell-text.c (ect_draw): Use CellViews now.
* e-table-item.c (eti_realize_cell_views): New routine: Realizes
the cell views
(eti_unrealize_cell_views): New routine: unrealizes the cell views.
* e-table-item.h: Move cell_views array here.
* table-test.c (value_at): Fix return value.
(main): use new invocation method.
* e-table-header-item.c (ethi_realize): Realize cells.
* e-table-item.c (eti_header_dim_changed): redraw before and after.
* e-table-header-item.c (ethi_event): Add continuous resizing.
1999-11-24 Miguel de Icaza <miguel@gnu.org>
* e-table-subset.h, e-table-subset.c: New files, used to implement
subset tables.
* e-table-sorted.h, e-table-sorted.c: Now they derive from
e-table-subset.
* e-cell.c, e-cell.h: realize method now return per view instance
data.
1999-11-20 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_draw): WOOOOHOOOOOoO! It took me quite a
while to figure this one out. Fixed.
* e-table-header-item.c (ethi_set_arg): Compute width, keep track
of it.
(ethi_add_table_header): Monitor changes to the Header model;
Queue updates.
(ethi_draw): Fix the redraw logic here.
* table-test.c (main): Change the sample code, so we can better
debug this.
* e-table-item.c (eti_header_structure_changed): Keep track of
width;
(eti_header_dim_changed): ditto.
(eti_draw): Many redraw fixes.
1999-11-19 Miguel de Icaza <miguel@gnu.org>
* e-table-item.c (eti_realize): Hook up; Load gcs.
(eti_unrealize): Hook up.
* e-table-sorted.c: Finished implementing.
1999-11-18 Miguel de Icaza <miguel@gnu.org>
* e-table-model.c (e_table_model_class_init): Add model_changed
signal here.
* e-table-item.c, e-table-item.h: New files. They implement the
view of the ETableModel as Canvas Items.
* e-table-header-item.c (ethi_set_arg): Ref header here.
(ethi_destroy): Unref it here.
1999-11-17 Ettore Perazzoli <ettore@gnu.org>
* e-msg-composer-address-dialog.c: Moved to `$(srcdir)/composer'.
* e-msg-composer-address-dialog.h: Likewise.
* e-msg-composer-address-entry.c: Likewise.
* e-msg-composer-address-entry.h: Likewise.
* e-msg-composer-attachment-bar.c: Likewise.
* e-msg-composer-attachment-bar.h: Likewise.
* e-msg-composer-attachment.c: Likewise.
* e-msg-composer-attachment.h: Likewise.
* e-msg-composer-hdrs.c: Likewise.
* e-msg-composer-hdrs.h: Likewise.
* e-msg-composer.c: Likewise.
* e-msg-composer.h: Likewise.
* e-msg-composer-address-dialog.glade: Likewise.
* e-msg-composer-attachment.glade: Likewise.
* e-msg-composer.glade: Likewise.
* Makefile.am: Updated accordingly.
Nov 14 1999 Elliot Lee
* Makefile.am: It's libevolutionwidgets.la, not .a
1999-11-14 Miguel de Icaza <miguel@gnu.org>
* e-table-header-item.c (is_pointer_on_division): Add resizing
capabilities.
* e-table-sorted.c: Finish implementation.
1999-11-13 Miguel de Icaza <miguel@gnu.org>
* e-table-sorted.c: Implement e-table-sorted object.
1999-11-12 Miguel de Icaza <miguel@gnu.org>
* e-table-header-item.c: Make the thing configurable.
* e-table-header-item.h: Add font field, location, height.
1999-11-12 Ettore Perazzoli <ettore@gnu.org>
* e-msg-composer-hdrs.c: New member `tooltips' in `struct
_EMsgComposerHdrsPrivate'.
(init): Initialize it.
(destroy): New function.
(class_init): Install it as the `destroy' GtkObject method.
(add_header): New parameters `tip', `tip_private'. Setup a
tooltip for the entry with them.
(setup_headers): Updated accordingly.
1999-11-11 Miguel de Icaza <miguel@gnu.org>
* e-table-header.c (e_table_header_add_column): Update offsets.
(eth_update_offsets): New routine.
* e-table-col.h, e-table-col.c: New files.
* e-table-header.h (e_table_header_get_selected_indexes):
Pretify.
* table-test.c (main): New file; used for testing ETable package.
* e-table-simple.h: Fix type.
1999-11-12 Ettore Perazzoli <ettore@gnu.org>
* e-msg-composer-address-dialog.glade: Cosmetical changes.
* e-msg-composer-attachment-bar.c (size_to_string): New helper
function.
(update): Put the size in the icon's label using this function.
(ICON_SEPARATORS): Remove '.' to avoid wrapping of the size string
on the decimal dot. But gnome-libs is broken and this has no real
effect! :-(
(e_msg_composer_attachment_bar_new): No longer make text editable.
Use the `GTK_SELECTION_MULTIPLE' selection mode.
(remove_selected): No longer assume only one attachment is
selected.
* e-msg-composer-attachment.c: #include <sys/stat.h>
(init): Initialize all the members.
(e_msg_composer_attachment_new): Set size using `stat()'.
* e-msg-composer-attachment.h: New member `size' in `struct
_EMsgComposerAttachment'.
* e-msg-composer.c (setup_signals): Connect `address_dialog_cb' to
the "show_address_dialog" signal of the header widget.
* e-msg-composer-hdrs.c (add_address_header): Renamed to
`add_header'. New parameter `addrbook_button': if true, use a
button instead of a label and make it trigger an
"show_address_dialog" signal.
(address_button_clicked_cb): Signal handler to handle this on a
"clicked" signal from the button.
(setup_headers): Updated accordingly. Also, make "Subject" the
last item. (This makes it look more like Outlook and friends.)
* e-msg-composer-hdrs.c: New signal "show_address_dialog".
* e-msg-composer-hdrs.h: Updated accordingly.
* e-msg-composer-hdrs.c (add_address_header): Reduce padding
considerably.
* e-msg-composer.c (e_msg_composer_construct): Do not use any
padding in the main vbox.
* Makefile.am: Moved the `e-table*' sources to `EXTRA_DIST'.
Compile as a shared library.
1999-11-08 Ettore Perazzoli <ettore@gnu.org>
* e-msg-composer-address-dialog.c: Implemented cut & paste for the
recipient lists.
(init): Initialize `cut_buffer'.
(destroy): Free it.
(recipient_clist_selection_get_cb): New function.
(recipient_clist_selection_received_cb): New function.
(recipient_clist_selection_clear_event_cb): New function.
(setup_recipient_list_signals): Install them as signal handlers
for "selection_get", "selection_received" and
"selection_clear_event" respectively.
(copy_recipient_cb): New function implementing the "copy"
operation.
(cut_recipient_cb): New function implementing the "cut" operation.
(paste_recipient_cb): New function implementing the "paste"
operation.
* e-msg-composer-address-dialog.h: New member `cut_buffer' in
`struct _EMsgComposerAddressDialog'.
1999-11-07 Ettore Perazzoli <ettore@gnu.org>
* e-msg-composer-address-dialog.c: New context menu
`recipient_list_popup_info' for the recipient CLists.
(recipient_clist_button_press_cb): New function.
(setup_signals): Install it as the "button_press_event" signal
handler for popping up the CList context menu.
* e-msg-composer.c (free_string_list): New helper function.
(setup_address_dialog): Setup the initial values in the address
dialog according to the ones in the header widget.
* e-msg-composer-hdrs.c (e_msg_composer_hdrs_get_to): New function.
(e_msg_composer_hdrs_get_cc): New function.
(e_msg_composer_hdrs_get_bcc): New function.
* e-msg-composer.c (setup_address_dialog): New helper function.
(address_dialog_cb): Use it.
* e-msg-composer-address-dialog.c (add_address): Do not set the
row data anymore. Instead, put the full address description
(i.e. complete with the email address, not just the full name) in
the CList.
(add_address): Do nothing if no item is selected in the address
CList.
(get_list): Get the address list from the CList without passing
through the address CList.
(set_list): New helper function.
(e_msg_composer_address_dialog_set_to_list): New function.
(e_msg_composer_address_dialog_set_cc_list): New function.
(e_msg_composer_address_dialog_set_bcc_list): New function.
* e-msg-composer.c (address_dialog_apply_cb): Apply values from
the address dialog into the composer.
* e-msg-composer-hdrs.c (e_msg_composer_hdrs_set_to): New function.
(e_msg_composer_hdrs_set_cc): New function.
(e_msg_composer_hdrs_set_bcc): New function.
* e-msg-composer-address-entry.c
(e_msg_composer_address_entry_set_list): New function.
* e-msg-composer-address-dialog.c (apply): New helper function.
(clicked): New function, `clicked' method for the `GnomeDialog'
class.
(class_init): Install it.
1999-11-06 Ettore Perazzoli <ettore@gnu.org>
* e-msg-composer-attachment-bar.c (destroy): Call the destroy
method of the parent class.
* e-msg-composer.c: #include "e-msg-composer-address-dialog.h".
(address_dialog_cb): New callback to start the address dialog.
(setup_signals): Connect it to the appropriate button/menu item.
(init): Initialize the new `address_dialog' member to NULL.
(destroy): Destroy the `address_dialog' if not NULL.
* e-msg-composer.h: New member `address_dialog' in `struct
_EMsgComposer'.
* e-msg-composer.glade: Added button to activate the address
composition dialog.
* e-msg-composer-address-dialog.h, e-msg-composer-address-dialog.c:
New files implementing the address composition dialog for Evolution.
* e-msg-composer-address-dialog.glade: New file.
* e-msg-composer-attachment.c: `signals' made static.
1999-11-05 Ettore Perazzoli <ettore@gnu.org>
* Makefile.am: Compile the new files in a `libevolutionwidgets'
library.
(CPPFLAGS): #define `E_GUIDIR'.
* e-msg-composer.c, e-msg-composer.h: New files implementing an
initial version of the Evolution message composer widget.
* e-msg-composer-address-entry.c, e-msg-composer-address-entry.h:
New files implementing a GtkEntry customized for entering email
address lists.
* e-msg-composer-attachment-bar.c, e-msg-composer-attachment-bar.h:
New files implementing a widget for editing mail attachments.
* e-msg-composer-attachment.c, e-msg-composer-attachment.h: New
files implementing file attachment objects for the message
composer.
* e-msg-composer-hdrs.c, e-msg-composer-hdrs.h: New files
implementing a widget for editing of email message headers.
* e-msg-composer-attachment.glade: New file.
* e-msg-composer.glade: New file.
1999-10-31 Miguel de Icaza <miguel@gnu.org>
* widgets/e-table-column.c, e-table-column.h: New file, implements the
e-table-column object.
* widget/e-table-model.h, e-table-model.c, e-table-simple.c,
e-table-simple.h: New files. Implements the column model and
a simple table wrapper.

View File

@ -1,65 +1,3 @@
SUBDIRS =
meeting-time-sel
INCLUDES = \
-I$(top_srcdir)/camel \
-I$(top_builddir)/camel \
$(GNOME_INCLUDEDIR)
noinst_LIBRARIES = \
libevolutionwidgets.a
libevolutionwidgets_a_SOURCES = \
e-cell.c \
e-cell.h \
e-cell-checkbox.c \
e-cell-checkbox.h \
e-cell-text.c \
e-cell-text.h \
e-cell-toggle.c \
e-cell-toggle.h \
e-cursors.c \
e-cursors.h \
e-table.c \
e-table.h \
e-table-col.c \
e-table-col.h \
e-table-group.c \
e-table-group.h \
e-table-header.c \
e-table-header.h \
e-table-header-item.c \
e-table-header-item.h \
e-table-item.c \
e-table-item.h \
e-table-model.c \
e-table-model.h \
e-table-simple.c \
e-table-simple.h \
e-table-sorted.c \
e-table-sorted.h \
e-table-subset.c \
e-table-subset.h
noinst_PROGRAMS = \
table-test
table_test_SOURCES = \
test-table.c \
test-check.c \
test-cols.c \
table-test.c
table_test_LDADD = \
$(EXTRA_GNOME_LIBS) \
libevolutionwidgets.a
table_test_LDFLAGS = `gnome-config --libs gdk_pixbuf`
EXTRA_DIST = \
sample.table \
add-col.xpm \
check-empty.xpm \
check-filled.xpm \
remove-col.xpm
SUBDIRS = \
util meeting-time-sel shortcut-bar e-table

View File

@ -1,113 +0,0 @@
The E-Table package implements an editable table that provides
user-defined rendering, user-defined editing, sorting and grouping of
the objects displayed.
It is inspired by Java's Swing JTable object. There are models for
the actual table contents and for the table headers; they are the
actual repository of information.
The objects are rendered by various view objects. In the current code
base, we use we use GnomeCanvasItems to do the rendering. One for
each table and one for the headers.
* The main widget
e-table.c, e-table.h:
Implements a full widget. Uses various components described
below. Handles column display as well as grouping/nesting
* The Models
All of them are GtkObjects.
e-table-model.h, e-table-model.c:
These implement the abstract E-Table-Model class. You
can derive this object to create your own data repository.
These emits signals to notify the views about selection, and
changes in the model.
e-table-simple.h, e-table-simple.c:
A simple implementation of e-table-model that uses callback
routines (you provide the callbacks). For lazy people, like
me.
e-cell.c, e-cell.h:
These are actually mis-named. Objects of type e-cell know
about rendering a single cell, and these are attached to the
e-table-cols (described next).
The user provides the various rendering modes as e-cells (they
are actually column-rendering repositories).
This is just an abstract class. I will provide various
e-cells: a text cell, a checkbox cell, an image cell, and
perhaps an n-state image cell (one that switches the image when
the cell is clicked).
e-table-col.h, e-table-col.c:
Describes a single column (the size, the string displayed, the
rendering function for each row and comparison function for
this field).
* The Views
e-table-header.h, e-table-header.c:
These implement the ETableHeaderItem canvas item. This item is
used both to control the columns displayed as well as displaying them.
They describe what columns are shown in the screen and in
which order.
These emit signals: column-size-changed and structure-changed
(if a column is added/removed)
e-table-item.c, e-table-item.h
This is a canvas item that renders the contents of a
ETableModel into the screen.
e-table-header-item.c, e-table-header-item.h
This canvas item renders the ETableHeader headings.
e-cell-text.c, e-cell-text.h
Not really a view, but actually a derivative of e-cell that
implements text display: supports justification and font
setting. Will add color in the future most likely
e-cell-toggle.c, e-cell-toggle.h
A derivative of e-cell as well that support N-toggle values
using images.
e-cell-check.c, e-cell-check.h
An e-cell-toggle with two states only (for checkboxes).
* The Filters
e-table-sorted.c, e-table-sorted.h
This is an ETableModel that can sort an existing ETableModel.
e-table-subset.c, e-table-subset.h
Not finished, but it is just an ETableModel that happens to be
a subset of another ETableModel.
* Everything
e-table.c, e-table.h
In the future these guys will implement the whole widget for
doing table editing. Nothing done about these yet.

View File

@ -1,24 +0,0 @@
Implement e-cell-height
Implement computation of heights from the e-cell-heights
Make sure we compute the height from that
Include spacing in columns and rows for the decoration lines
Add threshold to compute a "global" size
Implement the two methods for row finding: by full thing, or by a factor.
Add editing
mouse grabbing for scrolling
1. Make sure that all values are updated on header changes and table
model changes (they are slightly out of sync now)
* Correctness
* Make sure we can boot and shutdown with no memory leaks.
* Run Insure on the thing.
* Propagation
* Row changes should be reflected in the subsets.

View File

@ -1,22 +0,0 @@
/* XPM */
static char * add_col_xpm[] = {
"16 16 3 1",
" c None",
". c #000000",
"+ c #FFFFFF",
" ",
" ",
" ",
" ",
" .............. ",
" .++++++++++++. ",
" .++++++++++++. ",
" ....+++....... ",
" .+. ",
" . ",
" ",
" ",
" ",
" ",
" ",
" "};

View File

@ -1,21 +0,0 @@
/* XPM */
static char * check_empty_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" ............ ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" . . ",
" ............ ",
" ",
" "};

View File

@ -1,21 +0,0 @@
/* XPM */
static char * check_filled_xpm[] = {
"16 16 2 1",
" c None",
". c #000000",
" ",
" ",
" ............ ",
" . . ",
" . . . ",
" . .. . ",
" . ... . ",
" . . ... . ",
" . .. ... . ",
" . ..... . ",
" . ... . ",
" . . . ",
" . . ",
" ............ ",
" ",
" "};

View File

@ -1,44 +0,0 @@
/*
* e-cell-checkbox.c: Checkbox cell renderer
*
* Author:
* Miguel de Icaza (miguel@kernel.org)
*
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkwindow.h>
#include <gtk/gtksignal.h>
#include <gdk/gdkkeysyms.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-cell-checkbox.h"
#include "e-util.h"
#include "e-table-item.h"
#include "check-empty.xpm"
#include "check-filled.xpm"
#define PARENT_TYPE e_cell_toggle_get_type()
static GdkPixbuf *checks [2];
static void
e_cell_checkbox_class_init (GtkObjectClass *object_class)
{
checks [0] = gdk_pixbuf_new_from_xpm_data (check_empty_xpm);
checks [1] = gdk_pixbuf_new_from_xpm_data (check_filled_xpm);
}
E_MAKE_TYPE(e_cell_checkbox, "ECellCheckbox", ECellCheckbox, e_cell_checkbox_class_init, NULL, PARENT_TYPE);
ECell *
e_cell_checkbox_new (void)
{
ECellCheckbox *eccb = gtk_type_new (e_cell_checkbox_get_type ());
e_cell_toggle_construct (E_CELL_TOGGLE (eccb), 2, 2, checks);
return (ECell *) eccb;
}

View File

@ -1,24 +0,0 @@
#ifndef _E_CELL_CHECKBOX_H_
#define _E_CELL_CHECKBOX_H_
#include "e-cell-toggle.h"
#define E_CELL_CHECKBOX_TYPE (e_cell_checkbox_get_type ())
#define E_CELL_CHECKBOX(o) (GTK_CHECK_CAST ((o), E_CELL_CHECKBOX_TYPE, ECellCheckbox))
#define E_CELL_CHECKBOX_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CELL_CHECKBOX_TYPE, ECellCheckboxClass))
#define E_IS_CELL_CHECKBOX(o) (GTK_CHECK_TYPE ((o), E_CELL_CHECKBOX_TYPE))
#define E_IS_CELL_CHECKBOX_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_CHECKBOX_TYPE))
typedef struct {
ECellToggle parent;
} ECellCheckbox;
typedef struct {
ECellToggleClass parent_class;
} ECellCheckboxClass;
GtkType e_cell_checkbox_get_type (void);
ECell *e_cell_checkbox_new (void);
#endif /* _E_CELL_CHECKBOX_H_ */

View File

@ -1,9 +0,0 @@
ECell *
e_cell_string_new (void)
{
ECell *ecell;
ecell = gtk_type_new (ecell);
return ecell;
}

View File

@ -1,508 +0,0 @@
/*
* e-cell-text.c: Text cell renderer
*
* Author:
* Miguel de Icaza (miguel@kernel.org)
*
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkwindow.h>
#include <gtk/gtksignal.h>
#include <gdk/gdkkeysyms.h>
#include <libgnomeui/gnome-canvas.h>
#include <stdio.h>
#include "e-cell-text.h"
#include "e-util.h"
#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()
#define TEXT_PAD 2
typedef struct {
char *old_text;
GtkWidget *entry_top;
GtkEntry *entry;
/*
* Where the editing is taking place
*/
int model_col, view_col, row;
} CellEdit;
typedef struct {
ECellView cell_view;
GdkGC *gc;
GdkFont *font;
GnomeCanvas *canvas;
/*
* During edition.
*/
CellEdit *edit;
} ECellTextView;
static ECellClass *parent_class;
static void
ect_queue_redraw (ECellTextView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (
text_view->cell_view.e_table_item_view,
view_col, view_row, view_col, view_row);
}
/*
* Accept the currently edited text
*/
static void
ect_accept_edits (ECellTextView *text_view)
{
const char *text = gtk_entry_get_text (text_view->edit->entry);
CellEdit *edit = text_view->edit;
e_table_model_set_value_at (text_view->cell_view.e_table_model, edit->model_col, edit->row, text);
}
/*
* Shuts down the editing process
*/
static void
ect_stop_editing (ECellTextView *text_view)
{
CellEdit *edit = text_view->edit;
g_free (edit->old_text);
edit->old_text = NULL;
gtk_widget_destroy (edit->entry_top);
edit->entry_top = NULL;
edit->entry = NULL;
g_free (edit);
text_view->edit = NULL;
e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
}
/*
* Cancels the edits
*/
static void
ect_cancel_edit (ECellTextView *text_view)
{
ect_queue_redraw (text_view, text_view->edit->view_col, text_view->edit->row);
ect_stop_editing (text_view);
}
/*
* ECell::new_view method
*/
static ECellView *
ect_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view)
{
ECellText *ect = E_CELL_TEXT (ecell);
ECellTextView *text_view = g_new0 (ECellTextView, 1);
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (e_table_item_view)->canvas;
text_view->cell_view.ecell = ecell;
text_view->cell_view.e_table_model = table_model;
text_view->cell_view.e_table_item_view = e_table_item_view;
if (ect->font_name){
GdkFont *f;
f = gdk_fontset_load (ect->font_name);
text_view->font = f;
}
if (!text_view->font){
text_view->font = GTK_WIDGET (canvas)->style->font;
gdk_font_ref (text_view->font);
}
text_view->canvas = canvas;
return (ECellView *)text_view;
}
/*
* ECell::kill_view method
*/
static void
ect_kill_view (ECellView *ecv)
{
ECellTextView *text_view = (ECellTextView *) ecv;
gdk_font_unref (text_view->font);
text_view->font = NULL;
g_free (text_view);
}
/*
* ECell::realize method
*/
static void
ect_realize (ECellView *ecell_view)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
text_view->gc = gdk_gc_new (GTK_WIDGET (text_view->canvas)->window);
}
/*
* ECell::unrealize method
*/
static void
ect_unrealize (ECellView *ecv)
{
ECellTextView *text_view = (ECellTextView *) ecv;
gdk_gc_unref (text_view->gc);
text_view->gc = NULL;
}
/*
* ECell::draw method
*/
static void
ect_draw (ECellView *ecell_view, GdkDrawable *drawable,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellText *ect = E_CELL_TEXT (ecell_view->ecell);
ECellTextView *text_view = (ECellTextView *) ecell_view;
GtkWidget *w = GTK_WIDGET (text_view->canvas);
GdkRectangle rect;
const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row);
GdkFont *font = text_view->font;
const int height = font->ascent + font->descent;
int xoff;
gboolean edit_display = FALSE;
/*
* Figure if this cell is being edited
*/
if (text_view->edit){
CellEdit *edit = text_view->edit;
if ((edit->view_col == view_col) && (edit->row == row))
edit_display = TRUE;
}
/*
* Be a nice citizen: clip to the region we are supposed to draw on
*/
rect.x = x1;
rect.y = y1;
rect.width = x2 - x1;
rect.height = y2 - y1;
gdk_gc_set_clip_rectangle (text_view->gc, &rect);
if (edit_display){
CellEdit *edit = text_view->edit;
const char *text = gtk_entry_get_text (edit->entry);
GdkWChar *p, *text_wc = g_new (GdkWChar, strlen (text) + 1);
int text_wc_len = gdk_mbstowcs (text_wc, text, strlen (text));
const int cursor_pos = GTK_EDITABLE (edit->entry)->current_pos;
const int left_len = gdk_text_width_wc (text_view->font, text_wc, cursor_pos);
text_wc [text_wc_len] = 0;
/*
* Paint
*/
gdk_gc_set_foreground (text_view->gc, &w->style->base [GTK_STATE_NORMAL]);
gdk_draw_rectangle (drawable, text_view->gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
gdk_gc_set_foreground (text_view->gc, &w->style->text [GTK_STATE_NORMAL]);
{
GdkGC *gc = text_view->gc;
const int y = y2 - font->descent - ((y2-y1-height)/2);
int px, i;
/*
* Border
*/
x1 += 2;
x2--;
px = x1;
/*
* If the cursor is outside the visible range
*
* FIXME: we really want a better behaviour.
*/
if ((px + left_len) > x2)
px -= left_len - (x2-x1);
/*
* Draw
*/
for (i = 0, p = text_wc; *p; p++, i++){
gdk_draw_text_wc (
drawable, font, gc, px, y, p, 1);
if (i == cursor_pos){
gdk_draw_line (
drawable, gc,
px, y - font->ascent,
px, y + font->descent - 1);
}
px += gdk_text_width_wc (font, p, 1);
}
if (i == cursor_pos){
gdk_draw_line (
drawable, gc,
px, y - font->ascent,
px, y + font->descent - 1);
}
}
g_free (text_wc);
} else {
/*
* Regular cell
*/
GdkColor *background, *foreground;
int width;
/*
* Border
*/
x1++;
x2--;
/*
* Compute draw mode
*/
switch (ect->justify){
case GTK_JUSTIFY_LEFT:
xoff = 1;
break;
case GTK_JUSTIFY_RIGHT:
width = 1 + gdk_text_width (font, str, strlen (str));
xoff = (x2 - x1) - width;
break;
case GTK_JUSTIFY_CENTER:
xoff = ((x2 - x1) - gdk_text_width (font, str, strlen (str))) / 2;
break;
default:
xoff = 0;
g_warning ("Can not handle GTK_JUSTIFY_FILL");
break;
}
if (selected){
background = &w->style->bg [GTK_STATE_SELECTED];
foreground = &w->style->text [GTK_STATE_SELECTED];
} else {
background = &w->style->base [GTK_STATE_NORMAL];
foreground = &w->style->text [GTK_STATE_NORMAL];
}
gdk_gc_set_foreground (text_view->gc, background);
gdk_draw_rectangle (drawable, text_view->gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
gdk_gc_set_foreground (text_view->gc, foreground);
gdk_draw_string (
drawable, font, text_view->gc,
x1 + xoff,
y2 - font->descent - ((y2-y1-height)/2), str);
}
}
/*
* Selects the entire string
*/
static void
ect_edit_select_all (ECellTextView *text_view)
{
g_assert (text_view->edit);
gtk_editable_select_region (GTK_EDITABLE (text_view->edit->entry), 0, -1);
}
/*
* ECell::event method
*/
static gint
ect_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
switch (event->type){
case GDK_BUTTON_PRESS:
/*
* Adjust for the border we use
*/
event->button.x++;
printf ("Button pressed at %g %g\n", event->button.x, event->button.y);
if (text_view->edit){
printf ("FIXME: Should handle click here\n");
} else
e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row);
break;
case GDK_BUTTON_RELEASE:
/*
* Adjust for the border we use
*/
event->button.x++;
printf ("Button released at %g %g\n", event->button.x, event->button.y);
return TRUE;
case GDK_KEY_PRESS:
if (event->key.keyval == GDK_Escape){
ect_cancel_edit (text_view);
return TRUE;
}
if (!text_view->edit){
e_table_item_enter_edit (text_view->cell_view.e_table_item_view, view_col, row);
ect_edit_select_all (text_view);
}
gtk_widget_event (GTK_WIDGET (text_view->edit->entry), event);
ect_queue_redraw (text_view, view_col, row);
break;
case GDK_KEY_RELEASE:
break;
default:
return FALSE;
}
return TRUE;
}
/*
* ECell::height method
*/
static int
ect_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
return (text_view->font->ascent + text_view->font->descent) + TEXT_PAD;
}
/*
* Callback: invoked when the user pressed "enter" on the GtkEntry
*/
static void
ect_entry_activate (GtkEntry *entry, ECellTextView *text_view)
{
e_table_item_leave_edit (text_view->cell_view.e_table_item_view);
}
/*
* ECellView::enter_edit method
*/
static void *
ect_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
const char *str = e_table_model_value_at (ecell_view->e_table_model, model_col, row);
CellEdit *edit;
edit = g_new (CellEdit, 1);
text_view->edit = edit;
edit->model_col = model_col;
edit->view_col = view_col;
edit->row = row;
edit->entry = (GtkEntry *) gtk_entry_new ();
gtk_entry_set_text (edit->entry, str);
edit->old_text = g_strdup (str);
gtk_signal_connect (GTK_OBJECT (edit->entry), "activate",
GTK_SIGNAL_FUNC (ect_entry_activate), text_view);
/*
* The hack: create this window off-screen
*/
edit->entry_top = gtk_window_new (GTK_WINDOW_POPUP);
gtk_container_add (GTK_CONTAINER (edit->entry_top), GTK_WIDGET (edit->entry));
gtk_widget_set_uposition (edit->entry_top, 20000, 20000);
gtk_widget_show_all (edit->entry_top);
ect_queue_redraw (text_view, view_col, row);
return NULL;
}
/*
* ECellView::leave_edit method
*/
static void
ect_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
ECellTextView *text_view = (ECellTextView *) ecell_view;
if (text_view->edit){
ect_accept_edits (text_view);
ect_stop_editing (text_view);
} else {
/*
* We did invoke this leave edit internally
*/
}
}
/*
* GtkObject::destroy method
*/
static void
ect_destroy (GtkObject *object)
{
ECellText *ect = E_CELL_TEXT (object);
g_free (ect->font_name);
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
e_cell_text_class_init (GtkObjectClass *object_class)
{
ECellClass *ecc = (ECellClass *) object_class;
object_class->destroy = ect_destroy;
ecc->new_view = ect_new_view;
ecc->kill_view = ect_kill_view;
ecc->realize = ect_realize;
ecc->unrealize = ect_unrealize;
ecc->draw = ect_draw;
ecc->event = ect_event;
ecc->height = ect_height;
ecc->enter_edit = ect_enter_edit;
ecc->leave_edit = ect_leave_edit;
parent_class = gtk_type_class (PARENT_TYPE);
}
E_MAKE_TYPE(e_cell_text, "ECellText", ECellText, e_cell_text_class_init, NULL, PARENT_TYPE);
ECell *
e_cell_text_new (ETableModel *etm, const char *fontname, GtkJustification justify)
{
ECellText *ect = gtk_type_new (e_cell_text_get_type ());
ect->font_name = g_strdup (fontname);
ect->justify = justify;
return (ECell *) ect;
}

View File

@ -1,28 +0,0 @@
#ifndef _E_CELL_TEXT_H_
#define _E_CELL_TEXT_H_
#include <libgnomeui/gnome-canvas.h>
#include "e-cell.h"
#define E_CELL_TEXT_TYPE (e_cell_text_get_type ())
#define E_CELL_TEXT(o) (GTK_CHECK_CAST ((o), E_CELL_TEXT_TYPE, ECellText))
#define E_CELL_TEXT_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CELL_TEXT_TYPE, ECellTextClass))
#define E_IS_CELL_TEXT(o) (GTK_CHECK_TYPE ((o), E_CELL_TEXT_TYPE))
#define E_IS_CELL_TEXT_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_TEXT_TYPE))
typedef struct {
ECell parent;
GtkJustification justify;
char *font_name;
} ECellText;
typedef struct {
ECellClass parent_class;
} ECellTextClass;
GtkType e_cell_text_get_type (void);
ECell *e_cell_text_new (ETableModel *model, const char *fontname, GtkJustification justify);
#endif /* _E_CELL_TEXT_H_ */

View File

@ -1,298 +0,0 @@
/*
* e-cell-toggle.c: Multi-state image toggle cell object.
*
* Author:
* Miguel de Icaza (miguel@kernel.org)
*
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkwindow.h>
#include <gtk/gtksignal.h>
#include <gdk/gdkkeysyms.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-cell-toggle.h"
#include "e-util.h"
#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()
typedef struct {
ECellView cell_view;
GdkGC *gc;
GnomeCanvas *canvas;
} ECellToggleView;
static ECellClass *parent_class;
static void
etog_queue_redraw (ECellToggleView *text_view, int view_col, int view_row)
{
e_table_item_redraw_range (
text_view->cell_view.e_table_item_view,
view_col, view_row, view_col, view_row);
}
/*
* ECell::realize method
*/
static ECellView *
etog_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view)
{
ECellToggleView *toggle_view = g_new0 (ECellToggleView, 1);
ETableItem *eti = E_TABLE_ITEM (e_table_item_view);
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (eti)->canvas;
toggle_view->cell_view.ecell = ecell;
toggle_view->cell_view.e_table_model = table_model;
toggle_view->cell_view.e_table_item_view = e_table_item_view;
toggle_view->canvas = canvas;
return (ECellView *) toggle_view;
}
static void
etog_kill_view (ECellView *ecell_view)
{
g_free (ecell_view);
}
static void
etog_realize (ECellView *ecell_view)
{
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
toggle_view->gc = gdk_gc_new (GTK_WIDGET (toggle_view->canvas)->window);
}
/*
* ECell::unrealize method
*/
static void
etog_unrealize (ECellView *ecv)
{
ECellToggleView *toggle_view = (ECellToggleView *) ecv;
gdk_gc_unref (toggle_view->gc);
toggle_view->gc = NULL;
}
/*
* ECell::draw method
*/
static void
etog_draw (ECellView *ecell_view, GdkDrawable *drawable,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
GdkPixbuf *image;
ArtPixBuf *art;
int x, y, width, height;
const int value = GPOINTER_TO_INT (
e_table_model_value_at (ecell_view->e_table_model, model_col, row));
if (value >= toggle->n_states){
g_warning ("Value from the table model is %d, the states we support are [0..%d)\n",
value, toggle->n_states);
return;
}
/*
* Paint the background
*/
gdk_draw_rectangle (drawable, GTK_WIDGET (toggle_view->canvas)->style->white_gc, TRUE, x1, y1, x2 - x1, y2 - y1);
image = toggle->images [value];
art = image->art_pixbuf;
if ((x2 - x1) < art->width){
x = x1;
width = x2 - x1;
} else {
x = x1 + ((x2 - x1) - art->width) / 2;
width = art->width;
}
if ((y2 - y1) < art->height){
y = y1;
height = y2 - y1;
} else {
y = y1 + ((y2 - y1) - art->height) / 2;
height = art->height;
}
width = y2 - y1;
if (image->art_pixbuf->has_alpha){
GdkColor background;
guchar *buffer;
int alpha, ix, iy;
buffer = g_malloc (art->rowstride * art->height * 3);
background.red = 255;
background.green = 255;
background.blue = 255;
for (iy = 0; iy < art->height; iy++){
unsigned char *dest;
unsigned char *src;
dest = buffer + (iy * art->rowstride);
src = art->pixels + (iy * art->rowstride);
for (ix = 0; ix < art->width; ix++){
alpha = src [3];
if (alpha == 0){
*dest++ = background.red;
*dest++ = background.green;
*dest++ = background.blue;
src += 3;
} else if (alpha == 255){
*dest++ = *src++;
*dest++ = *src++;
*dest++ = *src++;
} else {
*dest++ = (background.red + ((*src++ - background.red) * alpha + 0x80)) >> 8;
*dest++ = (background.green + ((*src++ - background.green) * alpha + 0x80)) >> 8;
*dest++ = (background.blue + ((*src++ - background.blue) * alpha + 0x80)) >> 8;
}
src++;
}
}
gdk_draw_rgb_image_dithalign (
drawable, toggle_view->gc, x, y, width, height,
GDK_RGB_DITHER_NORMAL, buffer, art->rowstride, 0, 0);
g_free (buffer);
} else
gdk_draw_rgb_image_dithalign (
drawable, toggle_view->gc, x, y, width, height,
GDK_RGB_DITHER_NORMAL, art->pixels, art->rowstride, 0, 0);
}
static void
etog_set_value (ECellToggleView *toggle_view, int model_col, int view_col, int row, int value)
{
ECell *ecell = toggle_view->cell_view.ecell;
ECellToggle *toggle = E_CELL_TOGGLE (ecell);
if (value >= toggle->n_states)
value = 0;
e_table_model_set_value_at (toggle_view->cell_view.e_table_model,
model_col, row, GINT_TO_POINTER (value));
etog_queue_redraw (toggle_view, view_col, row);
}
/*
* ECell::event method
*/
static gint
etog_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
ECellToggleView *toggle_view = (ECellToggleView *) ecell_view;
void *_value = e_table_model_value_at (ecell_view->e_table_model, model_col, row);
const int value = GPOINTER_TO_INT (_value);
switch (event->type){
case GDK_BUTTON_RELEASE:
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
case GDK_KEY_PRESS:
if (event->key.keyval == GDK_space){
etog_set_value (toggle_view, model_col, view_col, row, value + 1);
return TRUE;
}
return FALSE;
default:
return FALSE;
}
return TRUE;
}
/*
* ECell::height method
*/
static int
etog_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
ECellToggle *toggle = E_CELL_TOGGLE (ecell_view->ecell);
return toggle->height;
}
static void
etog_destroy (GtkObject *object)
{
ECellToggle *etog = E_CELL_TOGGLE (object);
int i;
for (i = 0; i < etog->n_states; i++)
gdk_pixbuf_unref (etog->images [i]);
g_free (etog->images);
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
e_cell_toggle_class_init (GtkObjectClass *object_class)
{
ECellClass *ecc = (ECellClass *) object_class;
object_class->destroy = etog_destroy;
ecc->new_view = etog_new_view;
ecc->kill_view = etog_kill_view;
ecc->realize = etog_realize;
ecc->unrealize = etog_unrealize;
ecc->draw = etog_draw;
ecc->event = etog_event;
ecc->height = etog_height;
parent_class = gtk_type_class (PARENT_TYPE);
}
E_MAKE_TYPE(e_cell_toggle, "ECellToggle", ECellToggle, e_cell_toggle_class_init, NULL, PARENT_TYPE);
void
e_cell_toggle_construct (ECellToggle *etog, int border, int n_states, GdkPixbuf **images)
{
int max_height = 0;
int i;
etog->border = border;
etog->n_states = n_states;
etog->images = g_new (GdkPixbuf *, n_states);
for (i = 0; i < n_states; i++){
etog->images [i] = images [i];
gdk_pixbuf_ref (images [i]);
if (images [i]->art_pixbuf->height > max_height)
max_height = images [i]->art_pixbuf->height;
}
etog->height = max_height;
}
ECell *
e_cell_toggle_new (int border, int n_states, GdkPixbuf **images)
{
ECellToggle *etog = gtk_type_new (e_cell_toggle_get_type ());
e_cell_toggle_construct (etog, border, n_states, images);
return (ECell *) etog;
}

View File

@ -1,35 +0,0 @@
#ifndef _E_CELL_TOGGLE_H_
#define _E_CELL_TOGGLE_H_
#include <libgnomeui/gnome-canvas.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "e-cell.h"
#define E_CELL_TOGGLE_TYPE (e_cell_toggle_get_type ())
#define E_CELL_TOGGLE(o) (GTK_CHECK_CAST ((o), E_CELL_TOGGLE_TYPE, ECellToggle))
#define E_CELL_TOGGLE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CELL_TOGGLE_TYPE, ECellToggleClass))
#define E_IS_CELL_TOGGLE(o) (GTK_CHECK_TYPE ((o), E_CELL_TOGGLE_TYPE))
#define E_IS_CELL_TOGGLE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_TOGGLE_TYPE))
typedef struct {
ECell parent;
int border;
int n_states;
GdkPixbuf **images;
int height;
} ECellToggle;
typedef struct {
ECellClass parent_class;
} ECellToggleClass;
GtkType e_cell_toggle_get_type (void);
ECell *e_cell_toggle_new (int border, int n_states, GdkPixbuf **images);
void e_cell_toggle_construct (ECellToggle *etog, int border,
int n_states, GdkPixbuf **images);
#endif /* _E_CELL_TOGGLE_H_ */

View File

@ -1,176 +0,0 @@
/*
* e-cell.c: base class for cell renderers in e-table
*
* Author:
* Miguel de Icaza (miguel@kernel.org)
*
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
#include "e-cell.h"
#include "e-util.h"
#define PARENT_TYPE gtk_object_get_type()
static ECellView *
ec_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view)
{
return NULL;
}
static void
ec_realize (ECellView *e_cell)
{
}
static void
ec_kill_view (ECellView *ecell_view)
{
}
static void
ec_unrealize (ECellView *e_cell)
{
}
static void
ec_draw (ECellView *ecell_view, GdkDrawable *drawable,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2)
{
g_error ("e-cell-draw invoked\n");
}
static gint
ec_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static gint
ec_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
g_error ("e-cell-event invoked\n");
return 0;
}
static void
ec_focus (ECellView *ecell_view, int model_col, int view_col, int row, int x1, int y1, int x2, int y2)
{
ecell_view->focus_col = view_col;
ecell_view->focus_row = row;
ecell_view->focus_x1 = x1;
ecell_view->focus_y1 = y1;
ecell_view->focus_x2 = x2;
ecell_view->focus_y2 = y2;
}
static void
ec_unfocus (ECellView *ecell_view)
{
ecell_view->focus_col = -1;
ecell_view->focus_row = -1;
ecell_view->focus_x1 = -1;
ecell_view->focus_y1 = -1;
ecell_view->focus_x2 = -1;
ecell_view->focus_y2 = -1;
}
static void *
ec_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return NULL;
}
static void
ec_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *context)
{
}
static void
e_cell_class_init (GtkObjectClass *object_class)
{
ECellClass *ecc = (ECellClass *) object_class;
ecc->realize = ec_realize;
ecc->unrealize = ec_unrealize;
ecc->new_view = ec_new_view;
ecc->kill_view = ec_kill_view;
ecc->draw = ec_draw;
ecc->event = ec_event;
ecc->focus = ec_focus;
ecc->unfocus = ec_unfocus;
ecc->height = ec_height;
ecc->enter_edit = ec_enter_edit;
ecc->leave_edit = ec_leave_edit;
}
static void
e_cell_init (GtkObject *object)
{
}
E_MAKE_TYPE(e_cell, "ECell", ECell, e_cell_class_init, e_cell_init, PARENT_TYPE);
void
e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->event (
ecell_view, event, model_col, view_col, row);
}
ECellView *
e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view)
{
return E_CELL_CLASS (GTK_OBJECT (ecell)->klass)->new_view (
ecell, table_model, e_table_item_view);
}
void
e_cell_view_realize (ECellView *ecell_view)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->realize (ecell_view);
}
void
e_cell_kill_view (ECellView *ecell_view)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->kill_view (ecell_view);
}
void
e_cell_unrealize (ECellView *ecell_view)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->unrealize (ecell_view);
}
void
e_cell_draw (ECellView *ecell_view, GdkDrawable *drawable,
int model_col, int view_col, int row, gboolean selected, int x1, int y1, int x2, int y2)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->draw (
ecell_view, drawable, model_col, view_col, row, selected, x1, y1, x2, y2);
}
int
e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->height (
ecell_view, model_col, view_col, row);
}
void *
e_cell_enter_edit (ECellView *ecell_view, int model_col, int view_col, int row)
{
return E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->enter_edit (
ecell_view, model_col, view_col, row);
}
void
e_cell_leave_edit (ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context)
{
E_CELL_CLASS (GTK_OBJECT (ecell_view->ecell)->klass)->leave_edit (
ecell_view, model_col, view_col, row, edit_context);
}

View File

@ -1,73 +0,0 @@
#ifndef _E_CELL_H_
#define _E_CELL_H_
#include <gdk/gdktypes.h>
#include "e-table-model.h"
#define E_CELL_TYPE (e_cell_get_type ())
#define E_CELL(o) (GTK_CHECK_CAST ((o), E_CELL_TYPE, ECell))
#define E_CELL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CELL_TYPE, ECellClass))
#define E_IS_CELL(o) (GTK_CHECK_TYPE ((o), E_CELL_TYPE))
#define E_IS_CELL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CELL_TYPE))
typedef struct _ECell ECell;
typedef struct _ECellView ECellView;
struct _ECell {
GtkObject object;
};
struct _ECellView {
ECell *ecell;
ETableModel *e_table_model;
void *e_table_item_view;
gint focus_x1, focus_y1, focus_x2, focus_y2;
gint focus_col, focus_row;
};
#define E_CELL_IS_FOCUSED(ecell_view) (ecell_view->focus_x1 != -1)
typedef struct {
GtkObjectClass parent_class;
ECellView *(*new_view) (ECell *ecell, ETableModel *table_model, void *e_table_item_view);
void (*kill_view) (ECellView *ecell_view);
void (*realize) (ECellView *ecell_view);
void (*unrealize) (ECellView *ecell_view);
void (*draw) (ECellView *ecell_view, GdkDrawable *drawable,
int model_col, int view_col, int row,
gboolean selected, int x1, int y1, int x2, int y2);
gint (*event) (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
void (*focus) (ECellView *ecell_view, int model_col, int view_col,
int row, int x1, int y1, int x2, int y2);
void (*unfocus) (ECellView *ecell_view);
int (*height) (ECellView *ecell_view, int model_col, int view_col, int row);
void *(*enter_edit)(ECellView *ecell_view, int model_col, int view_col, int row);
void (*leave_edit)(ECellView *ecell_view, int model_col, int view_col, int row, void *context);
} ECellClass;
GtkType e_cell_get_type (void);
ECellView *e_cell_new_view (ECell *ecell, ETableModel *table_model, void *e_table_item_view);
void e_cell_kill_view (ECellView *ecell_view);
void e_cell_event (ECellView *ecell_view, GdkEvent *event, int model_col, int view_col, int row);
void e_cell_realize (ECellView *ecell_view);
void e_cell_unrealize (ECellView *ecell_view);
void e_cell_draw (ECellView *ecell_view, GdkDrawable *dr,
int model_col, int view_col, int row, gboolean selected,
int x1, int y1, int x2, int y2);
void e_cell_focus (ECellView *ecell_view, int model_col, int view_col, int row,
int x1, int y1, int x2, int y2);
void e_cell_unfocus (ECellView *ecell_view);
int e_cell_height (ECellView *ecell_view, int model_col, int view_col, int row);
void *e_cell_enter_edit(ECellView *ecell_view, int model_col, int view_col, int row);
void e_cell_leave_edit(ECellView *ecell_view, int model_col, int view_col, int row, void *edit_context);
#endif /* _E_CELL_H_ */

View File

@ -1,10 +0,0 @@
#ifndef _E_TABLE_COL_DND_H_
#define _E_TABLE_COL_DND_H_
#define TARGET_ETABLE_COL_TYPE "application/x-etable-column-header"
enum {
TARGET_ETABLE_COL_HEADER
};
#endif /* _E_TABLE_COL_DND_H_ */

View File

@ -1,64 +0,0 @@
/*
* E-table-col.c: ETableCol implementation
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
#include <gtk/gtkobject.h>
#include <gtk/gtksignal.h>
#include "e-table-col.h"
#include "e-util.h"
#define PARENT_TYPE (gtk_object_get_type ())
static GtkObjectClass *parent_class;
static void
etc_destroy (GtkObject *object)
{
ETableCol *etc = E_TABLE_COL (object);
g_free (etc->text);
(*parent_class->destroy)(object);
}
static void
e_table_col_class_init (GtkObjectClass *object_class)
{
parent_class = gtk_type_class (PARENT_TYPE);
object_class->destroy = etc_destroy;
}
E_MAKE_TYPE(e_table_col, "ETableCol", ETableCol, e_table_col_class_init, NULL, PARENT_TYPE);
ETableCol *
e_table_col_new (int col_idx, const char *text, int width, int min_width,
ECell *ecell, GCompareFunc compare, gboolean resizable)
{
ETableCol *etc;
g_return_val_if_fail (width >= 0, NULL);
g_return_val_if_fail (min_width >= 0, NULL);
g_return_val_if_fail (width >= min_width, NULL);
g_return_val_if_fail (compare != NULL, NULL);
etc = gtk_type_new (E_TABLE_COL_TYPE);
etc->col_idx = col_idx;
etc->text = g_strdup (text);
etc->width = width;
etc->min_width = min_width;
etc->ecell = ecell;
etc->compare = compare;
etc->selected = 0;
etc->resizeable = resizable;
return etc;
}

View File

@ -1,44 +0,0 @@
#ifndef _E_TABLE_COL_H_
#define _E_TABLE_COL_H_
#include "e-cell.h"
#define E_TABLE_COL_TYPE (e_table_col_get_type ())
#define E_TABLE_COL(o) (GTK_CHECK_CAST ((o), E_TABLE_COL_TYPE, ETableCol))
#define E_TABLE_COL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_COL_TYPE, ETableColClass))
#define E_IS_TABLE_COL(o) (GTK_CHECK_TYPE ((o), E_TABLE_COL_TYPE))
#define E_IS_TABLE_COL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_COL_TYPE))
typedef struct _ETableCol ETableCol;
/*
* Information about a single column
*/
struct _ETableCol {
GtkObject base;
char *text;
short width;
short min_width;
short x;
GCompareFunc compare;
unsigned int selected:1;
unsigned int resizeable:1;
int col_idx;
ECell *ecell;
};
typedef struct {
GtkObjectClass parent_class;
} ETableColClass;
GtkType e_table_col_get_type (void);
ETableCol *e_table_col_new (int col_idx, const char *text,
int width, int min_width,
ECell *ecell, GCompareFunc compare,
gboolean resizable);
void e_table_col_destroy (ETableCol *etc);
#endif /* _E_TABLE_COL_H_ */

View File

@ -1,199 +0,0 @@
/*
* E-table-column-view.c: A canvas view of the TableColumn.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* Copyright 1999, Helix Code, Inc.
*/
#include <config.h>
#include "e-table-column.h"
#include "e-table-column-view.h"
#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
static GnomeCanvasItemClass *etci_parent_class;
enum {
ARG_0,
ARG_TABLE_COLUMN
};
static void
etci_destroy (GtkObject *object)
{
ETableColumnItem *etcv = E_TABLE_COLUMN_VIEW (object);
gtk_object_unref (GTK_OBJECT (etcv));
if (GTK_OBJECT_CLASS (etcv_parent_class)->destroy)
(*GTK_OBJECT_CLASS (etcv_parent_class)->destroy) (object);
}
static void
etci_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
{
if (GNOME_CANVAS_ITEM_CLASS(item_bar_parent_class)->update)
(*GNOME_CANVAS_ITEM_CLASS(item_bar_parent_class)->update)(item, affine, clip_path, flags);
item->x1 = 0;
item->y1 = 0;
item->x2 = INT_MAX;
item->y2 = INT_MAX;
gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
}
static void
etci_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
GnomeCanvasItem *item;
ETableColumnItem *etci;
int v;
item = GNOME_CANVAS_ITEM (o);
etci = E_TABLE_COLUMN_ITEM (o);
switch (arg_id){
case ARG_TABLE_COLUMN:
etci->etci = GTK_VALUE_POINTER (*arg);
break;
}
etci_update (item, NULL, NULL, 0);
}
static void
etci_realize (GnomeCanvasItem *item)
{
ETableColumnItem *etci = E_TABLE_COLUMN_ITEM (item);
GdkWindow *window;
GdkColor c;
if (GNOME_CANVAS_ITEM_CLASS (etci_parent_class)-> realize)
(*GNOME_CANVAS_ITEM_CLASS (etci_parent_class)->realize)(item);
window = GTK_WIDGET (item->canvas)->window;
etci->gc = gdk_gc_new (window);
gnome_canvas_get_color (item->canvas, "black", &c);
gdk_gc_set_foreground (etci->gc, &c);
etci->normal_cursor = gdk_cursor_new (GDK_ARROW);
}
static void
etci_unrealize (GnomeCanvasItem *item)
{
ETableColumnItem *etci = E_TABLE_COLUMN_ITEM (item);
gdk_gc_unref (etci->gc);
etci->gc = NULL;
gdk_cursor_destroy (etci->change_cursor);
etci->change_cursor = NULL;
gdk_cursor_destroy (etci->normal_cursor);
etci->normal_cursor = NULL;
if (GNOME_CANVAS_ITEM_CLASS (etci_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (etci_parent_class)->unrealize)(item);
}
static void
etci_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x1, int y1, int width, int height)
{
ETableColumnItem *etci = E_TABLE_COLUMN_ITEM (item);
GnomeCanvas *canvas = item->canvas;
GdkGC *gc;
const int cols = e_table_column_count (etci->etc);
int x2 = x1 + width;
int col, total;
total = 0;
for (col = 0; col < cols; col++){
ETableCol *col = e_table_column_get_column (etci->etc, col);
const int col_width = col->width;
if (x1 > total + col_width)
continue;
if (x2 < total)
return;
gc = canvas->style->bg_gc [GTK_STATE_ACTIVE];
gdk_draw_rectangle (drawble, gc, TRUE,
gtk_draw_shadow (canvas->style, drawable, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
x, y, width, height
}
}
static double
etci_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
GnomeCanvasItem **actual_item)
{
*actual_item = *item;
return 0.0;
}
static void
etci_event (GnomeCanvasItem *item, GdkEvent *e)
{
switch (e->type){
default:
return FALSE;
}
return TRUE;
}
static void
etci_class_init (GtkObjectClass *object_class)
{
GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
object_class->destroy = etci_destroy;
object_class->set_arg = etci_set_arg;
item_class->update = etci_update;
item_class->realize = etci_realize;
item_class->unrealize = etci_unrealize;
item_class->draw = etci_draw;
item_class->point = etci_point;
item_class->event = etci_event;
gtk_object_add_arg_type ("ETableColumnItem::ETableColumn", GTK_TYPE_POINTER,
GTK_ARG_WRITABLE, ARG_TABLE_COLUMN);
}
static void
etci_init (GnomeCanvasItem *item)
{
item->x1 = 0;
item->y1 = 0;
item->x2 = 0;
item->y2 = 0;
}
GtkType
e_table_column_view_get_type (void)
{
static GtkType type = 0;
if (!type){
GtkTypeInfo info = {
"ETableColumnItem",
sizeof (ETableColumnItem),
sizeof (ETableColumnItemClass),
(GtkClassInitFunc) etci_class_init,
(GtkObjectInitFunc) etci_init,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
}
return type;
}

View File

@ -1,20 +0,0 @@
#ifndef _E_TABLE_COLUMN_VIEW_H
#defein _E_TABLE_COLUMN_VIEW_H
#include "e-table-column.h"
typedef struct {
GnomeCanvasItem parent;
ETableColumn *etc;
GdkGC *gc;
GdkCursor *change_cursor, *normal_cursor;
} ETableColumnView;
typedef struct {
GnomeCanvasItemClass parent_class;
} ETableColumnViewClass;
GtkType e_table_column_item_get_type (void);
#endif /* _E_TABLE_COLUMN_VIEW_H */

View File

@ -1,5 +0,0 @@
class ETableColumnModel {
virtual void add_column (ETableCol *et) = 0;
virtual ETableCol *get_column (int column);
virtual

View File

@ -1,293 +0,0 @@
/*
* e-table-column.c: TableColumn implementation
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
#include "e-table-column.h"
enum {
STRUCTURE_CHANGE,
DIMENSION_CHANGE,
LAST_SIGNAL
};
static guint etc_signals [LAST_SIGNAL] = { 0, };
static GtkObjectClass *e_table_column_parent_class;
static void
e_table_column_destroy (GtkObject *object)
{
ETableColumn *etc = E_TABLE_COLUMN (object);
const int cols = etc->col_count;
/*
* Destroy listeners
*/
for (l = etc->listeners; l; l = l->next)
g_free (l->data);
g_slist_free (etc->listeners);
etc->listeners = NULL;
/*
* Destroy columns
*/
for (i = 0; i < cols; i++)
e_table_column_remove (etc, i);
if (e_table_column_parent_class->destroy)
e_table_column_parent_class->destroy (object);
}
static void
e_table_column_class_init (GtkObjectClass *object_class)
{
object_class->destroy = e_table_column_destroy;
e_table_column_parent_class = (gtk_type_class (gtk_object_get_type ()));
etc_signals [STRUCTURE_CHANGE] =
gtk_signal_new ("structure_change",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableColumn, structure_change),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
etc_signals [DIMENSION_CHANGE] =
gtk_signal_new ("dimension_change",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableColumn, dimension_change),
gtk_marshal_NONE__INT,
GTK_TYPE_NONE, 1, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, etc_signals, LAST_SIGNAL);
}
GtkType
e_table_column_get_type (void)
{
static GtkType type = 0;
if (!type){
GtkTypeInfo info = {
"ETableColumn",
sizeof (ETableColumn),
sizeof (ETableColumnClass),
(GtkClassInitFunc) e_table_column_class_init,
(GtkObjectInitFunc) NULL,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (gtk_object_get_type (), &info);
}
return type;
}
static void
etc_do_insert (ETableColumn *etc, int pos, ETableCol *val)
{
memcpy (&etc->columns [pos+1], &etc->columns [pos],
sizeof (ETableCol *) * (etc->col_count - pos));
etc->columns [pos] = val;
}
void
e_table_column_add_column (ETableColumn *etc, ETableCol *tc, int pos)
{
ETableCol **new_ptr;
g_return_if_fail (etc != NULL);
g_return_if_fail (E_IS_TABLE_COLUMN (etc));
g_return_if_fail (tc != NULL);
g_return_if_fail (pos >= 0 && pos < etc->col_count);
if (pos == -1)
pos = etc->col_count;
etc->columns = g_realloc (etc->columns, sizeof (ETableCol *) * (etc->col_count + 1));
etc_do_insert (etc, pos, tc);
etc->col_count++;
gtk_signal_emit (GTK_OBJECT (etc), etc_signals [STRUCTURE_CHANGE]);
}
ETableCol *
e_table_column_get_column (ETableColumn *etc, int column)
{
g_return_val_if_fail (etc != NULL, NULL);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), NULL);
if (column < 0)
return NULL;
if (column >= etc->col_count)
return NULL;
return etc->columns [column];
}
int
e_table_column_count (ETableColumn *etc)
{
g_return_val_if_fail (etc != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), 0);
return etc->col_count;
}
int
e_table_column_index (ETableColumn *etc, const char *identifier)
{
int i;
g_return_val_if_fail (etc != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), 0);
g_return_val_if_fail (identifier != NULL, 0);
for (i = 0; i < etc->col_count; i++){
ETableCol *tc = etc->columns [i];
if (strcmp (i->id, identifier) == 0)
return i;
}
return -1;
}
int
e_table_column_get_index_at (ETableColumn *etc, int x_offset)
{
int i, total;
g_return_val_if_fail (etc != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), 0);
g_return_val_if_fail (identifier != NULL, 0);
total = 0;
for (i = 0; i < etc->col_count; i++){
total += etc->columns [i]->width;
if (x_offset < total)
return i;
}
return -1;
}
ETableCol **
e_table_column_get_columns (ETableColumn *etc)
{
ETableCol **ret;
int i;
g_return_val_if_fail (etc != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), 0);
ret = g_new (ETableCol *, etc->col_count + 1);
memcpy (ret, etc->columns, sizeof (ETableCol *) * etc->col_count);
ret [etc->col_count] = NULL;
return ret;
}
gboolean
e_table_column_selection_ok (ETableColumn *etc)
{
g_return_val_if_fail (etc != NULL, FALSE);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), FALSE);
return etc->selectable;
}
int
ve_table_column_get_selected (ETableColumn *etc)
{
int i;
int selected = 0;
g_return_val_if_fail (etc != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), 0);
for (i = 0; i < etc->col_count; i++){
if (etc->columns [i]->selected)
selected++;
}
return selected;
}
int
e_table_column_total_width (ETableColumn *etc)
{
int total;
g_return_val_if_fail (etc != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_COLUMN (etc), 0);
total = 0;
for (i = 0; i < etc->col_count; i++)
total += etc->columns [i].width;
return total;
}
static void
etc_do_remove (ETableColumn *etc, int idx)
{
memcpy (&etc->columns [idx], &etc->columns [idx+1],
sizeof (ETableCol *) * etc->col_count - idx);
etc->col_count--;
}
void
e_table_column_move (ETableColumn *etc, int source_index, int target_index)
{
g_return_if_fail (etc != NULL);
g_return_if_fail (E_IS_TABLE_COLUMN (etc));
g_return_if_fail (source_index >= 0);
g_return_if_fail (target_index >= 0);
g_return_if_fail (source_index < etc->col_count);
g_return_if_fail (target_index < etc->col_count);
old = etc->columns [source_index];
etc_do_remove (etc, source_index);
etc_do_insert (etc, target_index, old);
gtk_signal_emit (GTK_OBJECT (etc), etc_signals [STRUCTURE_CHANGE]);
}
void
e_table_column_remove (ETableColumn *etc, int idx)
{
g_return_if_fail (etc != NULL);
g_return_if_fail (E_IS_TABLE_COLUMN (etc));
g_return_if_fail (idx >= 0);
g_return_if_fail (idx < etc->col_count);
etc_do_remove (etc, idx);
gtk_signal_emit (GTK_OBJECT (etc), etc_signals [STRUCTURE_CHANGE]);
}
void
e_table_column_set_selection (ETableColumn *etc, gboolean allow_selection);
{
}
void
e_table_column_set_size (ETableColumn *etc, int idx, int size)
{
g_return_if_fail (etc != NULL);
g_return_if_fail (E_IS_TABLE_COLUMN (etc));
g_return_if_fail (idx >= 0);
g_return_if_fail (idx < etc->col_count);
g_return_if_fail (size > 0);
etc->columns [idx]->width = size;
gtk_signal_emit (GTK_OBJECT (etc), etc_signals [SIZE_CHANGE], idx);
}

View File

@ -1,269 +0,0 @@
/*
* E-Table-Group.c: Implements the grouping objects for elements on a table
*
* Author:
* Miguel de Icaza (miguel@gnu.org()
*
* Copyright 1999, Helix Code, Inc.
*/
#include <config.h>
#include <gtk/gtksignal.h>
#include "e-table-group.h"
#include "e-table-item.h"
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include "e-util.h"
#define TITLE_HEIGHT 16
#define GROUP_INDENT 10
#define PARENT_TYPE gnome_canvas_group_get_type ()
static GnomeCanvasGroupClass *etg_parent_class;
enum {
HEIGHT_CHANGED,
LAST_SIGNAL
};
static gint etg_signals [LAST_SIGNAL] = { 0, };
static void
etg_destroy (GtkObject *object)
{
ETableGroup *etg = E_TABLE_GROUP (object);
GTK_OBJECT_CLASS (etg_parent_class)->destroy (object);
}
static void
etg_dim (ETableGroup *etg, int *width, int *height)
{
GSList *l;
*width = *height = 0;
for (l = etg->children; l; l = l->next){
GnomeCanvasItem *child = l->data;
*height += child->y2 - child->y1;
*width += child->x2 - child->x1;
}
if (!etg->transparent){
*height += TITLE_HEIGHT;
*width += GROUP_INDENT;
}
}
void
e_table_group_construct (GnomeCanvasGroup *parent, ETableGroup *etg,
ETableCol *ecol, gboolean open,
gboolean transparent)
{
gnome_canvas_item_constructv (GNOME_CANVAS_ITEM (etg), parent, 0, NULL);
etg->ecol = ecol;
etg->open = open;
etg->transparent = transparent;
etg_dim (etg, &etg->width, &etg->height);
if (!etg->transparent)
etg->rect = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (etg),
gnome_canvas_rect_get_type (),
"fill_color", "gray",
"outline_color", "gray20",
"x1", 0.0,
"y1", 0.0,
"x2", (double) etg->width,
"y2", (double) etg->height,
NULL);
#if 0
/*
* Reparent the child into our space.
*/
gnome_canvas_item_reparent (child, GNOME_CANVAS_GROUP (etg));
gnome_canvas_item_set (
child,
"x", (double) GROUP_INDENT,
"y", (double) TITLE_HEIGHT,
NULL);
/*
* Force dimension computation
*/
GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (
GNOME_CANVAS_ITEM (etg), NULL, NULL, GNOME_CANVAS_UPDATE_REQUESTED);
#endif
}
GnomeCanvasItem *
e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
gboolean open, gboolean transparent)
{
ETableGroup *etg;
g_return_val_if_fail (parent != NULL, NULL);
g_return_val_if_fail (ecol != NULL, NULL);
etg = gtk_type_new (e_table_group_get_type ());
e_table_group_construct (parent, etg, ecol, open, transparent);
return GNOME_CANVAS_ITEM (etg);
}
static void
etg_relayout (GnomeCanvasItem *eti, ETableGroup *etg)
{
GSList *l;
int height = etg->transparent ? 0 : GROUP_INDENT;
gboolean move = FALSE;
printf ("Relaying out\n");
for (l = etg->children; l->next; l = l->next){
GnomeCanvasItem *child = l->data;
height += child->y2 - child->y1;
if (child == eti)
move = TRUE;
if (move){
printf ("Moving item %p\n", child);
gnome_canvas_item_set (
child,
"y", (double) height,
NULL);
}
}
if (height != etg->height){
etg->height = height;
gtk_signal_emit (GTK_OBJECT (etg), etg_signals [HEIGHT_CHANGED]);
}
}
void
e_table_group_add (ETableGroup *etg, GnomeCanvasItem *item)
{
double x1, y1, x2, y2;
g_return_if_fail (etg != NULL);
g_return_if_fail (item != NULL);
g_return_if_fail (E_IS_TABLE_GROUP (etg));
g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
etg->children = g_slist_append (etg->children, item);
GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT (etg)->klass)->bounds (etg, &x1, &y1, &x2, &y2);
if (GTK_OBJECT (etg)->flags & GNOME_CANVAS_ITEM_REALIZED){
GSList *l;
int height = etg->transparent ? 0 : TITLE_HEIGHT;
int x = etg->transparent ? 0 : GROUP_INDENT;
for (l = etg->children; l->next; l = l->next){
GnomeCanvasItem *child = l->data;
height += child->y2 - child->y1;
}
printf ("Positioning item %p at %d\n", item, height);
gnome_canvas_item_set (
item,
"y", (double) height,
"x", (double) x,
NULL);
if (E_IS_TABLE_ITEM (item)){
printf ("Table item! ---------\n");
gtk_signal_connect (GTK_OBJECT (item), "height_changed",
GTK_SIGNAL_FUNC (etg_relayout), etg);
}
}
}
static void
etg_realize (GnomeCanvasItem *item)
{
ETableGroup *etg = E_TABLE_GROUP (item);
GSList *l;
int height = 0;
GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->realize (item);
for (l = etg->children; l; l = l->next){
GnomeCanvasItem *child = l->data;
printf ("During realization for child %p -> %d\n", child, height);
gnome_canvas_item_set (
child,
"y", (double) height,
NULL);
height += child->y2 - child->y1;
}
}
static void
etg_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
{
ETableGroup *etg = E_TABLE_GROUP (item);
GNOME_CANVAS_ITEM_CLASS (etg_parent_class)->update (item, affine, clip_path, flags);
if (!etg->transparent){
int current_width, current_height;
etg_dim (etg, &current_width, &current_height);
if ((current_height != etg->height) || (current_width != etg->width)){
etg->width = current_width;
etg->height = current_height;
gnome_canvas_item_set (
etg->rect,
"x1", 0.0,
"y1", 0.0,
"x2", (double) etg->width,
"y2", (double) etg->height,
NULL);
}
}
}
static void
etg_class_init (GtkObjectClass *object_class)
{
GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
object_class->destroy = etg_destroy;
item_class->realize = etg_realize;
item_class->update = etg_update;
etg_parent_class = gtk_type_class (PARENT_TYPE);
etg_signals [HEIGHT_CHANGED] =
gtk_signal_new ("height_changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableGroupClass, height_changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, etg_signals, LAST_SIGNAL);
}
E_MAKE_TYPE (e_table_group, "ETableGroup", ETableGroup, etg_class_init, NULL, PARENT_TYPE);

View File

@ -1,63 +0,0 @@
#ifndef _E_TABLE_TREE_H_
#define _E_TABLE_TREE_H_
#include <libgnomeui/gnome-canvas.h>
#include "e-table-model.h"
#include "e-table-header.h"
#define E_TABLE_GROUP_TYPE (e_table_group_get_type ())
#define E_TABLE_GROUP(o) (GTK_CHECK_CAST ((o), E_TABLE_GROUP_TYPE, ETableGroup))
#define E_TABLE_GROUP_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_GROUP_TYPE, ETableGroupClass))
#define E_IS_TABLE_GROUP(o) (GTK_CHECK_TYPE ((o), E_TABLE_GROUP_TYPE))
#define E_IS_TABLE_GROUP_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_GROUP_TYPE))
typedef struct {
GnomeCanvasGroup group;
/*
* The ETableCol used to group this set
*/
ETableCol *ecol;
/*
* The canvas rectangle that contains the children
*/
GnomeCanvasItem *rect;
/*
* Dimensions of the ETableGroup
*/
int width, height;
/*
* State: the ETableGroup is open or closed
*/
guint open:1;
/*
* Whether we should add indentation and open/close markers,
* or if we just act as containers of subtables.
*/
guint transparent:1;
/*
* List of GnomeCanvasItems we stack
*/
GSList *children;
} ETableGroup;
typedef struct {
GnomeCanvasGroupClass parent_class;
void (*height_changed) (ETableGroup *etg);
} ETableGroupClass;
GnomeCanvasItem *e_table_group_new (GnomeCanvasGroup *parent, ETableCol *ecol,
gboolean open, gboolean transparent);
void e_table_group_construct (GnomeCanvasGroup *parent, ETableGroup *etg,
ETableCol *ecol, gboolean open, gboolean transparent);
void e_table_group_add (ETableGroup *etg, GnomeCanvasItem *child);
GtkType e_table_group_get_type (void);
#endif /* _E_TABLE_TREE_H_ */

View File

@ -1,793 +0,0 @@
/*
* E-table-column-view.c: A canvas item based view of the ETableColumn.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* Copyright 1999, Helix Code, Inc.
*/
#include <config.h>
#include <gtk/gtksignal.h>
#include <gtk/gtkdnd.h>
#include <libgnomeui/gnome-canvas.h>
#include <libgnomeui/gnome-canvas-util.h>
#include <libgnomeui/gnome-canvas-polygon.h>
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-col-dnd.h"
#include "e-cursors.h"
#include "add-col.xpm"
#include "remove-col.xpm"
/* Padding above and below of the string in the header display */
#define PADDING 4
/* Defines the tolerance for proximity of the column division to the cursor position */
#define TOLERANCE 2
#define ETHI_RESIZING(x) ((x)->resize_col != -1)
#define PARENT_OBJECT_TYPE gnome_canvas_item_get_type ()
#define ELEMENTS(x) (sizeof (x) / sizeof (x[0]))
static GnomeCanvasItemClass *ethi_parent_class;
/*
* DnD icons
*/
static GdkColormap *dnd_colormap;
static GdkPixmap *remove_col_pixmap, *remove_col_mask;
static GdkPixmap *add_col_pixmap, *add_col_mask;
enum {
ARG_0,
ARG_TABLE_HEADER,
ARG_TABLE_X,
ARG_TABLE_Y,
ARG_TABLE_FONTSET
};
static GtkTargetEntry ethi_drag_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static GtkTargetEntry ethi_drop_types [] = {
{ TARGET_ETABLE_COL_TYPE, 0, TARGET_ETABLE_COL_HEADER },
};
static void
ethi_destroy (GtkObject *object)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (object);
gtk_object_unref (GTK_OBJECT (ethi->eth));
if (GTK_OBJECT_CLASS (ethi_parent_class)->destroy)
(*GTK_OBJECT_CLASS (ethi_parent_class)->destroy) (object);
}
static void
ethi_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)(item, affine, clip_path, flags);
item->x1 = ethi->x1;
item->y1 = ethi->y1;
item->x2 = ethi->x1 + ethi->width;
item->y2 = ethi->y1 + ethi->height;
gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
}
static void
ethi_font_load (ETableHeaderItem *ethi, char *font)
{
if (ethi->font)
gdk_font_unref (ethi->font);
ethi->font = gdk_fontset_load (font);
if (ethi->font == NULL)
ethi->font = gdk_font_load ("fixed");
ethi->height = ethi->font->ascent + ethi->font->descent + PADDING;
}
static void
ethi_drop_table_header (ETableHeaderItem *ethi)
{
GtkObject *header;
if (!ethi->eth)
return;
header = GTK_OBJECT (ethi->eth);
gtk_signal_disconnect (header, ethi->structure_change_id);
gtk_signal_disconnect (header, ethi->dimension_change_id);
gtk_object_unref (header);
ethi->eth = NULL;
ethi->width = 0;
}
static void
structure_changed (ETableHeader *header, ETableHeaderItem *ethi)
{
ethi->width = e_table_header_total_width (header);
ethi_update (GNOME_CANVAS_ITEM (ethi), NULL, NULL, 0);
}
static void
dimension_changed (ETableHeader *header, int col, ETableHeaderItem *ethi)
{
ethi->width = e_table_header_total_width (header);
ethi_update (GNOME_CANVAS_ITEM (ethi), NULL, NULL, 0);
}
static void
ethi_add_table_header (ETableHeaderItem *ethi, ETableHeader *header)
{
ethi->eth = header;
gtk_object_ref (GTK_OBJECT (ethi->eth));
ethi->width = e_table_header_total_width (header);
ethi->structure_change_id = gtk_signal_connect (
GTK_OBJECT (header), "structure_change",
GTK_SIGNAL_FUNC(structure_changed), ethi);
ethi->dimension_change_id = gtk_signal_connect (
GTK_OBJECT (header), "dimension_change",
GTK_SIGNAL_FUNC(dimension_changed), ethi);
}
static void
ethi_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
GnomeCanvasItem *item;
ETableHeaderItem *ethi;
item = GNOME_CANVAS_ITEM (o);
ethi = E_TABLE_HEADER_ITEM (o);
switch (arg_id){
case ARG_TABLE_HEADER:
ethi_drop_table_header (ethi);
ethi_add_table_header (ethi, GTK_VALUE_POINTER (*arg));
break;
case ARG_TABLE_X:
ethi->x1 = GTK_VALUE_INT (*arg);
break;
case ARG_TABLE_Y:
ethi->y1 = GTK_VALUE_INT (*arg);
break;
case ARG_TABLE_FONTSET:
ethi_font_load (ethi, GTK_VALUE_STRING (*arg));
break;
}
ethi_update (item, NULL, NULL, 0);
}
static int
ethi_find_col_by_x (ETableHeaderItem *ethi, int x)
{
const int cols = e_table_header_count (ethi->eth);
int x1 = ethi->x1;
int col;
if (x < x1)
return -1;
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
if ((x >= x1) && (x <= x1 + ecol->width))
return col;
x1 += ecol->width;
}
return -1;
}
static void
ethi_remove_drop_marker (ETableHeaderItem *ethi)
{
if (ethi->drag_mark == -1)
return;
ethi->drag_mark = -1;
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark_item = NULL;
}
static void
ethi_add_drop_marker (ETableHeaderItem *ethi, int col)
{
GnomeCanvasPoints *points;
int x;
if (ethi->drag_mark == col)
return;
if (ethi->drag_mark_item)
gtk_object_destroy (GTK_OBJECT (ethi->drag_mark_item));
ethi->drag_mark = col;
ethi->drag_mark_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_group_get_type (),
"x", 0,
"y", 0,
NULL);
points = gnome_canvas_points_new (3);
x = e_table_header_col_diff (ethi->eth, 0, col);
points->coords [0] = ethi->x1 + x - 5;
points->coords [1] = ethi->y1;
points->coords [2] = points->coords [0] + 10;
points->coords [3] = points->coords [1];
points->coords [4] = ethi->x1 + x;
points->coords [5] = ethi->y1 + 5;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
points->coords [0] --;
points->coords [1] += ethi->height - 1;
points->coords [3] = points->coords [1];
points->coords [5] = points->coords [1] - 6;
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (ethi->drag_mark_item),
gnome_canvas_polygon_get_type (),
"points", points,
"fill_color", "red",
NULL);
gnome_canvas_points_unref (points);
}
#define gray50_width 2
#define gray50_height 2
static char gray50_bits [] = {
0x02, 0x01, };
static void
ethi_add_destroy_marker (ETableHeaderItem *ethi)
{
double x1;
if (ethi->remove_item)
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
if (!ethi->stipple)
ethi->stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
x1 = ethi->x1 + (double) e_table_header_col_diff (ethi->eth, 0, ethi->drag_col);
ethi->remove_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (GNOME_CANVAS_ITEM (ethi)->canvas->root),
gnome_canvas_rect_get_type (),
"x1", x1 + 1,
"y1", (double) ethi->y1 + 1,
"x2", (double) x1 + e_table_header_col_diff (ethi->eth, ethi->drag_col, ethi->drag_col+1) - 2,
"y2", (double) ethi->y1 + ethi->height - 2,
"fill_color", "red",
"fill_stipple", ethi->stipple,
NULL);
}
static void
ethi_remove_destroy_marker (ETableHeaderItem *ethi)
{
if (!ethi->remove_item)
return;
gtk_object_destroy (GTK_OBJECT (ethi->remove_item));
ethi->remove_item = NULL;
}
static gboolean
ethi_drag_motion (GtkObject *canvas, GdkDragContext *context,
gint x, gint y, guint time,
ETableHeaderItem *ethi)
{
if ((x >= ethi->x1) && (x <= (ethi->x1 + ethi->width)) &&
(y >= ethi->y1) && (y <= (ethi->y1 + ethi->height))){
int col;
col = ethi_find_col_by_x (ethi, x);
if (col != -1){
ethi_remove_destroy_marker (ethi);
ethi_add_drop_marker (ethi, col);
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
} else {
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
gdk_drag_status (context, context->suggested_action, time);
return TRUE;
}
static void
ethi_drag_end (GtkWidget *canvas, GdkDragContext *context, ETableHeaderItem *ethi)
{
ethi_remove_drop_marker (ethi);
ethi_remove_destroy_marker (ethi);
ethi->drag_col = -1;
}
static void
ethi_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, ETableHeaderItem *ethi)
{
ethi_remove_drop_marker (ethi);
ethi_add_destroy_marker (ethi);
}
static void
ethi_realize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GdkWindow *window;
GdkColor c;
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)-> realize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->realize)(item);
window = GTK_WIDGET (item->canvas)->window;
ethi->gc = gdk_gc_new (window);
gnome_canvas_get_color (item->canvas, "black", &c);
gdk_gc_set_foreground (ethi->gc, &c);
ethi->normal_cursor = gdk_cursor_new (GDK_ARROW);
if (!ethi->font)
ethi_font_load (ethi, "fixed");
/*
* Now, configure DnD
*/
gtk_drag_dest_set (GTK_WIDGET (item->canvas), GTK_DEST_DEFAULT_ALL,
ethi_drop_types, ELEMENTS (ethi_drop_types),
GDK_ACTION_MOVE);
ethi->drag_motion_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_motion",
GTK_SIGNAL_FUNC (ethi_drag_motion), ethi);
ethi->drag_leave_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_leave",
GTK_SIGNAL_FUNC (ethi_drag_leave), ethi);
ethi->drag_end_id = gtk_signal_connect (
GTK_OBJECT (item->canvas), "drag_end",
GTK_SIGNAL_FUNC (ethi_drag_end), ethi);
}
static void
ethi_unrealize (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
gdk_gc_unref (ethi->gc);
ethi->gc = NULL;
gdk_cursor_destroy (ethi->normal_cursor);
ethi->normal_cursor = NULL;
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_motion_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_end_id);
gtk_signal_disconnect (GTK_OBJECT (item->canvas), ethi->drag_leave_id);
if (ethi->stipple){
gdk_bitmap_unref (ethi->stipple);
ethi->stipple = NULL;
}
if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)
(*GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->unrealize)(item);
}
static void
draw_button (ETableHeaderItem *ethi, ETableCol *col,
GdkDrawable *drawable, GdkGC *gc, GtkStyle *style,
int x, int y, int width, int height)
{
GdkRectangle clip;
int xtra;
gdk_draw_rectangle (
drawable, gc, TRUE,
x + 1, y + 1, width - 2, height -2);
gtk_draw_shadow (
style, drawable,
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
x , y, width, height);
clip.x = x + 2;
clip.y = y + 2;
clip.width = width - 4;
clip.height = ethi->height;
gdk_gc_set_clip_rectangle (ethi->gc, &clip);
/* Center the thing */
xtra = (clip.width - gdk_string_measure (ethi->font, col->text))/2;
if (xtra < 0)
xtra = 0;
/* Skip over border */
x += xtra + 2;
gdk_draw_text (
drawable, ethi->font,
ethi->gc, x, y + ethi->height - PADDING,
col->text, strlen (col->text));
}
static void
ethi_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int width, int height)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GnomeCanvas *canvas = item->canvas;
GdkGC *gc;
const int cols = e_table_header_count (ethi->eth);
int x1, x2;
int col;
#if 0
printf ("My coords are: %g %g %g %g\n",
item->x1, item->y1, item->x2, item->y2);
#endif
x1 = x2 = ethi->x1;
for (col = 0; col < cols; col++, x1 = x2){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
int col_width;
if (col == ethi->resize_col)
col_width = ethi->resize_width;
else
col_width = ecol->width;
x2 += col_width;
if (x1 > (x + width))
break;
if (x2 < x)
continue;
gc = GTK_WIDGET (canvas)->style->bg_gc [GTK_STATE_ACTIVE];
draw_button (ethi, ecol, drawable, gc,
GTK_WIDGET (canvas)->style,
x1 - x, ethi->y1 - y, col_width, ethi->height);
}
}
static double
ethi_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
GnomeCanvasItem **actual_item)
{
*actual_item = item;
return 0.0;
}
/*
* is_pointer_on_division:
*
* Returns whether @pos is a column header division; If @the_total is not NULL,
* then the actual position is returned here. If @return_ecol is not NULL,
* then the ETableCol that actually contains this point is returned here
*/
static gboolean
is_pointer_on_division (ETableHeaderItem *ethi, int pos, int *the_total, int *return_col)
{
const int cols = e_table_header_count (ethi->eth);
int col, total;
total = 0;
for (col = 0; col < cols; col++){
ETableCol *ecol = e_table_header_get_column (ethi->eth, col);
total += ecol->width;
if ((total - TOLERANCE < pos ) && (pos < total + TOLERANCE)){
if (return_col)
*return_col = col;
if (the_total)
*the_total = total;
return TRUE;
}
if (total > pos + TOLERANCE)
return FALSE;
}
return FALSE;
}
#define convert(c,sx,sy,x,y) gnome_canvas_w2c (c,sx,sy,x,y)
static void
set_cursor (ETableHeaderItem *ethi, int pos)
{
GtkWidget *canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
/* We might be invoked before we are realized */
if (!canvas->window)
return;
if (is_pointer_on_division (ethi, pos, NULL, NULL))
e_cursor_set (canvas->window, E_CURSOR_SIZE_X);
else
e_cursor_set (canvas->window, E_CURSOR_ARROW);
}
static void
ethi_request_redraw (ETableHeaderItem *ethi)
{
GnomeCanvas *canvas = GNOME_CANVAS_ITEM (ethi)->canvas;
/*
* request a redraw
*/
gnome_canvas_request_redraw (
canvas, ethi->x1, ethi->y1, ethi->x1 + ethi->width, ethi->x1 + ethi->height);
}
static void
ethi_end_resize (ETableHeaderItem *ethi, int new_size)
{
e_table_header_set_size (ethi->eth, ethi->resize_col, new_size);
ethi->resize_col = -1;
ethi_request_redraw (ethi);
}
static gboolean
ethi_maybe_start_drag (ETableHeaderItem *ethi, GdkEventMotion *event)
{
if (!ethi->maybe_drag)
return FALSE;
if (MAX (abs (ethi->click_x - event->x),
abs (ethi->click_y - event->y)) <= 3)
return FALSE;
return TRUE;
}
static void
ethi_start_drag (ETableHeaderItem *ethi, GdkEvent *event)
{
GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM (ethi)->canvas);
GtkTargetList *list;
GdkDragContext *context;
ethi->drag_col = ethi_find_col_by_x (ethi, event->motion.x);
if (ethi->drag_col == -1)
return;
list = gtk_target_list_new (ethi_drag_types, ELEMENTS (ethi_drag_types));
context = gtk_drag_begin (widget, list, GDK_ACTION_MOVE, 1, event);
ethi->maybe_drag = FALSE;
}
/*
* Handles the events on the ETableHeaderItem, particularly it handles resizing
*/
static int
ethi_event (GnomeCanvasItem *item, GdkEvent *e)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
GnomeCanvas *canvas = item->canvas;
const gboolean resizing = ETHI_RESIZING (ethi);
int x, y, start, col;
switch (e->type){
case GDK_ENTER_NOTIFY:
convert (canvas, e->crossing.x, e->crossing.y, &x, &y);
set_cursor (ethi, x);
break;
case GDK_LEAVE_NOTIFY:
e_cursor_set (GTK_WIDGET (canvas)->window, E_CURSOR_ARROW);
break;
case GDK_MOTION_NOTIFY:
convert (canvas, e->motion.x, e->motion.y, &x, &y);
if (resizing){
int new_width;
if (ethi->resize_guide == NULL){
/* Quick hack until I actually bind the views */
ethi->resize_guide = GINT_TO_POINTER (1);
gnome_canvas_item_grab (item,
GDK_POINTER_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK,
e_cursor_get (E_CURSOR_SIZE_X),
e->button.time);
}
new_width = x - ethi->resize_start_pos;
if (new_width <= 0)
break;
if (new_width < ethi->resize_min_width)
break;
ethi_request_redraw (ethi);
ethi->resize_width = new_width;
e_table_header_set_size (ethi->eth, ethi->resize_col, ethi->resize_width);
ethi_request_redraw (ethi);
} else if (ethi_maybe_start_drag (ethi, &e->motion)){
ethi_start_drag (ethi, e);
} else
set_cursor (ethi, x);
break;
case GDK_BUTTON_PRESS:
convert (canvas, e->button.x, e->button.y, &x, &y);
if (is_pointer_on_division (ethi, x, &start, &col)){
ETableCol *ecol;
/*
* Record the important bits.
*
* By setting resize_pos to a non -1 value,
* we know that we are being resized (used in the
* other event handlers).
*/
ecol = e_table_header_get_column (ethi->eth, col);
if (!ecol->resizeable)
break;
ethi->resize_col = col;
ethi->resize_width = ecol->width;
ethi->resize_start_pos = start - ecol->width;
ethi->resize_min_width = ecol->min_width;
} else {
if (e->button.button == 1){
ethi->click_x = e->button.x;
ethi->click_y = e->button.y;
ethi->maybe_drag = TRUE;
}
}
break;
case GDK_2BUTTON_PRESS:
if (!resizing)
break;
if (e->button.button != 1)
break;
break;
case GDK_BUTTON_RELEASE: {
gboolean needs_ungrab = FALSE;
if (ethi->resize_col != -1){
needs_ungrab = (ethi->resize_guide != NULL);
ethi_end_resize (ethi, ethi->resize_width);
}
if (needs_ungrab)
gnome_canvas_item_ungrab (item, e->button.time);
ethi->maybe_drag = FALSE;
break;
}
default:
return FALSE;
}
return TRUE;
}
static void
ethi_class_init (GtkObjectClass *object_class)
{
GnomeCanvasItemClass *item_class = (GnomeCanvasItemClass *) object_class;
ethi_parent_class = gtk_type_class (PARENT_OBJECT_TYPE);
object_class->destroy = ethi_destroy;
object_class->set_arg = ethi_set_arg;
item_class->update = ethi_update;
item_class->realize = ethi_realize;
item_class->unrealize = ethi_unrealize;
item_class->draw = ethi_draw;
item_class->point = ethi_point;
item_class->event = ethi_event;
gtk_object_add_arg_type ("ETableHeaderItem::ETableHeader", GTK_TYPE_POINTER,
GTK_ARG_WRITABLE, ARG_TABLE_HEADER);
gtk_object_add_arg_type ("ETableHeaderItem::x", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_TABLE_X);
gtk_object_add_arg_type ("ETableHeaderItem::y", GTK_TYPE_INT,
GTK_ARG_WRITABLE, ARG_TABLE_Y);
gtk_object_add_arg_type ("ETableHeaderItem::fontset", GTK_TYPE_STRING,
GTK_ARG_WRITABLE, ARG_TABLE_FONTSET);
/*
* Create our pixmaps for DnD
*/
dnd_colormap = gtk_widget_get_default_colormap ();
remove_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&remove_col_mask, NULL, remove_col_xpm);
add_col_pixmap = gdk_pixmap_colormap_create_from_xpm_d (
NULL, dnd_colormap,
&add_col_mask, NULL, add_col_xpm);
}
static void
ethi_init (GnomeCanvasItem *item)
{
ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
ethi->resize_col = -1;
item->x1 = 0;
item->y1 = 0;
item->x2 = 0;
item->y2 = 0;
ethi->drag_col = -1;
ethi->drag_mark = -1;
}
GtkType
e_table_header_item_get_type (void)
{
static GtkType type = 0;
if (!type){
GtkTypeInfo info = {
"ETableHeaderItem",
sizeof (ETableHeaderItem),
sizeof (ETableHeaderItemClass),
(GtkClassInitFunc) ethi_class_init,
(GtkObjectInitFunc) ethi_init,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (PARENT_OBJECT_TYPE, &info);
}
return type;
}

View File

@ -1,56 +0,0 @@
#ifndef _E_TABLE_HEADER_ITEM_H_
#define _E_TABLE_HEADER_ITEM_H_
#include <libgnomeui/gnome-canvas.h>
#include "e-table-header.h"
#define E_TABLE_HEADER_ITEM_TYPE (e_table_header_item_get_type ())
#define E_TABLE_HEADER_ITEM(o) (GTK_CHECK_CAST ((o), E_TABLE_HEADER_ITEM_TYPE, ETableHeaderItem))
#define E_TABLE_HEADER_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_HEADER_ITEM_TYPE, ETableHeaderItemClass))
#define E_IS_TABLE_HEADER_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_HEADER_ITEM_TYPE))
#define E_IS_TABLE_HEADER_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_HEADER_ITEM_TYPE))
typedef struct {
GnomeCanvasItem parent;
ETableHeader *eth;
GdkGC *gc;
GdkCursor *change_cursor, *normal_cursor;
short x1, y1, height, width;
GdkFont *font;
/*
* Used during resizing; Could be shorts
*/
int resize_col;
int resize_width;
int resize_start_pos;
int resize_min_width;
GtkObject *resize_guide;
/*
* Ids
*/
int structure_change_id, dimension_change_id;
/*
* For dragging columns
*/
guint maybe_drag:1;
guint dnd_ready:1;
int click_x, click_y;
int drag_col, drag_mark;
guint drag_motion_id, drag_end_id, drag_leave_id;
GnomeCanvasItem *drag_mark_item, *remove_item;
GdkBitmap *stipple;
} ETableHeaderItem;
typedef struct {
GnomeCanvasItemClass parent_class;
} ETableHeaderItemClass;
GtkType e_table_header_item_get_type (void);
#endif /* _E_TABLE_HEADER_ITEM_H_ */

View File

@ -1,342 +0,0 @@
/*
* E-table-col-head.c: TableColHead implementation
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* (C) 1999 Helix Code, Inc
*/
#include <config.h>
#include <gtk/gtkobject.h>
#include <gtk/gtksignal.h>
#include "e-table-header.h"
enum {
STRUCTURE_CHANGE,
DIMENSION_CHANGE,
LAST_SIGNAL
};
static guint eth_signals [LAST_SIGNAL] = { 0, };
static GtkObjectClass *e_table_header_parent_class;
static void
e_table_header_destroy (GtkObject *object)
{
ETableHeader *eth = E_TABLE_HEADER (object);
const int cols = eth->col_count;
int i;
/*
* Destroy columns
*/
for (i = 0; i < cols; i++){
e_table_header_remove (eth, i);
}
if (e_table_header_parent_class->destroy)
e_table_header_parent_class->destroy (object);
}
static void
e_table_header_class_init (GtkObjectClass *object_class)
{
object_class->destroy = e_table_header_destroy;
e_table_header_parent_class = (gtk_type_class (gtk_object_get_type ()));
eth_signals [STRUCTURE_CHANGE] =
gtk_signal_new ("structure_change",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableHeaderClass, structure_change),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
eth_signals [DIMENSION_CHANGE] =
gtk_signal_new ("dimension_change",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableHeaderClass, dimension_change),
gtk_marshal_NONE__INT,
GTK_TYPE_NONE, 1, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, eth_signals, LAST_SIGNAL);
}
GtkType
e_table_header_get_type (void)
{
static GtkType type = 0;
if (!type){
GtkTypeInfo info = {
"ETableHeader",
sizeof (ETableHeader),
sizeof (ETableHeaderClass),
(GtkClassInitFunc) e_table_header_class_init,
(GtkObjectInitFunc) NULL,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (gtk_object_get_type (), &info);
}
return type;
}
ETableHeader *
e_table_header_new (void)
{
ETableHeader *eth;
eth = gtk_type_new (e_table_header_get_type ());
return eth;
}
static void
eth_do_insert (ETableHeader *eth, int pos, ETableCol *val)
{
memcpy (&eth->columns [pos+1], &eth->columns [pos],
sizeof (ETableCol *) * (eth->col_count - pos));
eth->columns [pos] = val;
}
static void
eth_update_offsets (ETableHeader *eth)
{
int i;
int x = 0;
for (i = 0; i < eth->col_count; i++){
ETableCol *etc = eth->columns [i];
etc->x = x;
x += etc->width;
}
}
void
e_table_header_add_column (ETableHeader *eth, ETableCol *tc, int pos)
{
g_return_if_fail (eth != NULL);
g_return_if_fail (E_IS_TABLE_HEADER (eth));
g_return_if_fail (tc != NULL);
g_return_if_fail (E_IS_TABLE_COL (tc));
g_return_if_fail (pos >= -1 && pos <= eth->col_count);
if (pos == -1)
pos = eth->col_count;
eth->columns = g_realloc (eth->columns, sizeof (ETableCol *) * (eth->col_count + 1));
/*
* We are the primary owners of the column
*/
gtk_object_ref (GTK_OBJECT (tc));
gtk_object_sink (GTK_OBJECT (tc));
eth_do_insert (eth, pos, tc);
eth->col_count++;
eth_update_offsets (eth);
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]);
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE]);
}
ETableCol *
e_table_header_get_column (ETableHeader *eth, int column)
{
g_return_val_if_fail (eth != NULL, NULL);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), NULL);
if (column < 0)
return NULL;
if (column >= eth->col_count)
return NULL;
return eth->columns [column];
}
int
e_table_header_count (ETableHeader *eth)
{
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
return eth->col_count;
}
int
e_table_header_index (ETableHeader *eth, int col)
{
g_return_val_if_fail (eth != NULL, -1);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), -1);
g_return_val_if_fail (col < eth->col_count, -1);
return eth->columns [col]->col_idx;
}
int
e_table_header_get_index_at (ETableHeader *eth, int x_offset)
{
int i, total;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
total = 0;
for (i = 0; i < eth->col_count; i++){
total += eth->columns [i]->width;
if (x_offset < total)
return i;
}
return -1;
}
ETableCol **
e_table_header_get_columns (ETableHeader *eth)
{
ETableCol **ret;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
ret = g_new (ETableCol *, eth->col_count + 1);
memcpy (ret, eth->columns, sizeof (ETableCol *) * eth->col_count);
ret [eth->col_count] = NULL;
return ret;
}
gboolean
e_table_header_selection_ok (ETableHeader *eth)
{
g_return_val_if_fail (eth != NULL, FALSE);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), FALSE);
return eth->selectable;
}
int
e_table_header_get_selected (ETableHeader *eth)
{
int i;
int selected = 0;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
for (i = 0; i < eth->col_count; i++){
if (eth->columns [i]->selected)
selected++;
}
return selected;
}
int
e_table_header_total_width (ETableHeader *eth)
{
int total, i;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
total = 0;
for (i = 0; i < eth->col_count; i++)
total += eth->columns [i]->width;
return total;
}
static void
eth_do_remove (ETableHeader *eth, int idx, gboolean do_unref)
{
if (do_unref)
gtk_object_unref (GTK_OBJECT (eth->columns [idx]));
memcpy (&eth->columns [idx], &eth->columns [idx+1],
sizeof (ETableCol *) * eth->col_count - idx);
eth->col_count--;
}
void
e_table_header_move (ETableHeader *eth, int source_index, int target_index)
{
ETableCol *old;
g_return_if_fail (eth != NULL);
g_return_if_fail (E_IS_TABLE_HEADER (eth));
g_return_if_fail (source_index >= 0);
g_return_if_fail (target_index >= 0);
g_return_if_fail (source_index < eth->col_count);
g_return_if_fail (target_index < eth->col_count);
old = eth->columns [source_index];
eth_do_remove (eth, source_index, FALSE);
eth_do_insert (eth, target_index, old);
eth_update_offsets (eth);
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]);
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE]);
}
void
e_table_header_remove (ETableHeader *eth, int idx)
{
g_return_if_fail (eth != NULL);
g_return_if_fail (E_IS_TABLE_HEADER (eth));
g_return_if_fail (idx >= 0);
g_return_if_fail (idx < eth->col_count);
eth_do_remove (eth, idx, TRUE);
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [STRUCTURE_CHANGE]);
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE]);
}
void
e_table_header_set_selection (ETableHeader *eth, gboolean allow_selection)
{
}
void
e_table_header_set_size (ETableHeader *eth, int idx, int size)
{
g_return_if_fail (eth != NULL);
g_return_if_fail (E_IS_TABLE_HEADER (eth));
g_return_if_fail (idx >= 0);
g_return_if_fail (idx < eth->col_count);
g_return_if_fail (size > 0);
eth->columns [idx]->width = size;
gtk_signal_emit (GTK_OBJECT (eth), eth_signals [DIMENSION_CHANGE], idx);
}
int
e_table_header_col_diff (ETableHeader *eth, int start_col, int end_col)
{
int total, col;
g_return_val_if_fail (eth != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_HEADER (eth), 0);
{
const int max_col = eth->col_count;
total = 0;
for (col = start_col; col < end_col; col++){
if (col == max_col)
break;
total += eth->columns [col]->width;
}
}
return total;
}

View File

@ -1,65 +0,0 @@
#ifndef _E_TABLE_COLUMN_H_
#define _E_TABLE_COLUMN_H_
#include <gtk/gtkobject.h>
#include <gdk/gdk.h>
#include "e-table-col.h"
typedef struct _ETableHeader ETableHeader;
#define E_TABLE_HEADER_TYPE (e_table_header_get_type ())
#define E_TABLE_HEADER(o) (GTK_CHECK_CAST ((o), E_TABLE_HEADER_TYPE, ETableHeader))
#define E_TABLE_HEADER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_HEADER_TYPE, ETableHeaderClass))
#define E_IS_TABLE_HEADER(o) (GTK_CHECK_TYPE ((o), E_TABLE_HEADER_TYPE))
#define E_IS_TABLE_HEADER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_HEADER_TYPE))
/*
* A Columnar header.
*/
struct _ETableHeader {
GtkObject base;
int col_count;
ETableCol **columns;
gboolean selectable;
};
typedef struct {
GtkObjectClass parent_class;
void (*structure_change) (ETableHeader *eth);
void (*dimension_change) (ETableHeader *eth, int col);
} ETableHeaderClass;
GtkType e_table_header_get_type (void);
ETableHeader *e_table_header_new (void);
void e_table_header_add_column (ETableHeader *eth,
ETableCol *tc, int pos);
ETableCol * e_table_header_get_column (ETableHeader *eth,
int column);
int e_table_header_count (ETableHeader *eth);
int e_table_header_index (ETableHeader *eth,
int col);
int e_table_header_get_index_at (ETableHeader *eth,
int x_offset);
ETableCol **e_table_header_get_columns (ETableHeader *eth);
gboolean e_table_header_selection_ok (ETableHeader *eth);
int e_table_header_get_selected (ETableHeader *eth);
int e_table_header_total_width (ETableHeader *eth);
void e_table_header_move (ETableHeader *eth,
int source_index,
int target_index);
void e_table_header_remove (ETableHeader *eth, int idx);
void e_table_header_set_size (ETableHeader *eth, int idx, int size);
void e_table_header_set_selection (ETableHeader *eth,
gboolean allow_selection);
int e_table_header_col_diff (ETableHeader *eth,
int start_col, int end_col);
GList *e_table_header_get_selected_indexes(ETableHeader *eth);
#endif /* _E_TABLE_HEADER_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,106 +0,0 @@
#ifndef _E_TABLE_ITEM_H_
#define _E_TABLE_ITEM_H_
#include <libgnomeui/gnome-canvas.h>
#include "e-table-model.h"
#include "e-table-header.h"
#define E_TABLE_ITEM_TYPE (e_table_item_get_type ())
#define E_TABLE_ITEM(o) (GTK_CHECK_CAST ((o), E_TABLE_ITEM_TYPE, ETableItem))
#define E_TABLE_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_ITEM_TYPE, ETableItemClass))
#define E_IS_TABLE_ITEM(o) (GTK_CHECK_TYPE ((o), E_TABLE_ITEM_TYPE))
#define E_IS_TABLE_ITEM_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_ITEM_TYPE))
typedef struct {
GnomeCanvasItem parent;
ETableModel *table_model;
ETableHeader *header;
int x1, y1;
int width, height;
int cols, rows;
/*
* Ids for the signals we connect to
*/
int header_dim_change_id;
int header_structure_change_id;
int table_model_change_id;
int table_model_row_change_id;
GdkGC *fill_gc;
GdkGC *grid_gc;
GdkGC *focus_gc;
GdkBitmap *stipple;
unsigned int draw_grid:1;
unsigned int draw_focus:1;
unsigned int mode_spreadsheet:1;
unsigned int renderers_can_change_size:1;
unsigned int cell_views_realized:1;
int focused_col, focused_row;
/*
* Realized views, per column
*/
ECellView **cell_views;
int n_cells;
/*
* Lengh Threshold: above this, we stop computing correctly
* the size
*/
int length_threshold;
GSList *selection;
GtkSelectionMode selection_mode;
/*
* During edition
*/
int editing_col, editing_row;
void *edit_ctx;
} ETableItem;
typedef struct {
GnomeCanvasItemClass parent_class;
void (*row_selection) (ETableItem *eti, int row, gboolean selected);
void (*height_changed) (ETableItem *eti);
} ETableItemClass;
GtkType e_table_item_get_type (void);
/*
* Focus
*/
void e_table_item_focus (ETableItem *eti, int col, int row);
void e_table_item_unfocus (ETableItem *eti);
/*
* Selection
*/
void e_table_item_select_row (ETableItem *e_table_Item, int row);
void e_table_item_unselect_row (ETableItem *e_table_Item, int row);
/*
* Handling the selection
*/
const GSList*e_table_item_get_selection (ETableItem *e_table_Item);
GtkSelectionMode e_table_item_get_selection_mode (ETableItem *e_table_Item);
void e_table_item_set_selection_mode (ETableItem *e_table_Item,
GtkSelectionMode selection_mode);
gboolean e_table_item_is_row_selected (ETableItem *e_table_Item,
int row);
void e_table_item_leave_edit (ETableItem *eti);
void e_table_item_enter_edit (ETableItem *eti, int col, int row);
void e_table_item_redraw_range (ETableItem *eti,
int start_col, int start_row,
int end_col, int end_row);
#endif /* _E_TABLE_ITEM_H_ */

View File

@ -1,176 +0,0 @@
/*
* e-table-model.c: a Table Model
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* (C) 1999 Helix Code, Inc.
*/
#include <config.h>
#include <gtk/gtksignal.h>
#include "e-table-model.h"
#define ETM_CLASS(e) ((ETableModelClass *)((GtkObject *)e)->klass)
static GtkObjectClass *e_table_model_parent_class;
enum {
MODEL_CHANGED,
MODEL_ROW_CHANGED,
MODEL_CELL_CHANGED,
ROW_SELECTION,
LAST_SIGNAL
};
static guint e_table_model_signals [LAST_SIGNAL] = { 0, };
int
e_table_model_column_count (ETableModel *e_table_model)
{
g_return_val_if_fail (e_table_model != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), 0);
return ETM_CLASS (e_table_model)->column_count (e_table_model);
}
int
e_table_model_row_count (ETableModel *e_table_model)
{
g_return_val_if_fail (e_table_model != NULL, 0);
g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), 0);
return ETM_CLASS (e_table_model)->row_count (e_table_model);
}
void *
e_table_model_value_at (ETableModel *e_table_model, int col, int row)
{
g_return_val_if_fail (e_table_model != NULL, NULL);
g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), NULL);
return ETM_CLASS (e_table_model)->value_at (e_table_model, col, row);
}
void
e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
ETM_CLASS (e_table_model)->set_value_at (e_table_model, col, row, data);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_ROW_CHANGED], row);
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_CELL_CHANGED], col, row);
/*
* Notice that "model_changed" is not emitted
*/
}
gboolean
e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row)
{
g_return_val_if_fail (e_table_model != NULL, FALSE);
g_return_val_if_fail (E_IS_TABLE_MODEL (e_table_model), FALSE);
return ETM_CLASS (e_table_model)->is_cell_editable (e_table_model, col, row);
}
static void
e_table_model_destroy (GtkObject *object)
{
if (e_table_model_parent_class->destroy)
(*e_table_model_parent_class->destroy)(object);
}
static void
e_table_model_class_init (GtkObjectClass *object_class)
{
e_table_model_parent_class = gtk_type_class (gtk_object_get_type ());
object_class->destroy = e_table_model_destroy;
e_table_model_signals [MODEL_CHANGED] =
gtk_signal_new ("model_changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableModelClass, model_changed),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
e_table_model_signals [MODEL_ROW_CHANGED] =
gtk_signal_new ("model_row_changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableModelClass, model_row_changed),
gtk_marshal_NONE__INT,
GTK_TYPE_NONE, 1, GTK_TYPE_INT);
e_table_model_signals [MODEL_CELL_CHANGED] =
gtk_signal_new ("model_cell_changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ETableModelClass, model_cell_changed),
gtk_marshal_NONE__INT_INT,
GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, e_table_model_signals, LAST_SIGNAL);
}
GtkType
e_table_model_get_type (void)
{
static GtkType type = 0;
if (!type){
GtkTypeInfo info = {
"ETableModel",
sizeof (ETableModel),
sizeof (ETableModelClass),
(GtkClassInitFunc) e_table_model_class_init,
(GtkObjectInitFunc) NULL,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (gtk_object_get_type (), &info);
}
return type;
}
void
e_table_model_changed (ETableModel *e_table_model)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_CHANGED]);
}
void
e_table_model_row_changed (ETableModel *e_table_model, int row)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_ROW_CHANGED], row);
}
void
e_table_model_cell_changed (ETableModel *e_table_model, int col, int row)
{
g_return_if_fail (e_table_model != NULL);
g_return_if_fail (E_IS_TABLE_MODEL (e_table_model));
gtk_signal_emit (GTK_OBJECT (e_table_model),
e_table_model_signals [MODEL_CELL_CHANGED], col, row);
}

View File

@ -1,58 +0,0 @@
#ifndef _E_TABLE_MODEL_H_
#define _E_TABLE_MODEL_H_
#include <gtk/gtkobject.h>
#define E_TABLE_MODEL_TYPE (e_table_model_get_type ())
#define E_TABLE_MODEL(o) (GTK_CHECK_CAST ((o), E_TABLE_MODEL_TYPE, ETableModel))
#define E_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_MODEL_TYPE, ETableModelClass))
#define E_IS_TABLE_MODEL(o) (GTK_CHECK_TYPE ((o), E_TABLE_MODEL_TYPE))
#define E_IS_TABLE_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_MODEL_TYPE))
typedef struct {
GtkObject base;
} ETableModel;
typedef struct {
GtkObjectClass parent_class;
/*
* Virtual methods
*/
int (*column_count) (ETableModel *etm);
int (*row_count) (ETableModel *etm);
void *(*value_at) (ETableModel *etm, int col, int row);
void (*set_value_at) (ETableModel *etm, int col, int row, const void *value);
gboolean (*is_cell_editable) (ETableModel *etm, int col, int row);
/*
* Signals
*/
/*
* Major structural changes: model_changed
* Changes only in a row: row_changed
* Only changes in a cell: cell_changed
*/
void (*model_changed) (ETableModel *etm);
void (*model_row_changed) (ETableModel *etm, int row);
void (*model_cell_changed) (ETableModel *etm, int col, int row);
} ETableModelClass;
GtkType e_table_model_get_type (void);
int e_table_model_column_count (ETableModel *e_table_model);
const char *e_table_model_column_name (ETableModel *e_table_model, int col);
int e_table_model_row_count (ETableModel *e_table_model);
void *e_table_model_value_at (ETableModel *e_table_model, int col, int row);
void e_table_model_set_value_at (ETableModel *e_table_model, int col, int row, const void *data);
gboolean e_table_model_is_cell_editable (ETableModel *e_table_model, int col, int row);
/*
* Routines for emitting signals on the e_table
*/
void e_table_model_changed (ETableModel *e_table_model);
void e_table_model_row_changed (ETableModel *e_table_model, int row);
void e_table_model_cell_changed (ETableModel *e_table_model, int col, int row);
#endif /* _E_TABLE_MODEL_H_ */

View File

@ -1,20 +0,0 @@
/*
* E-table-render.c: Various renderers
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* Copyright 1999, Helix Code, Inc.
*/
#include <config.h>
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-col.h"
#include "e-table-render.h"
void
e_table_render_string (ERenderContext *ctxt)
{
printf ("Rendering string: %s\n", ctxt->render_data);
}

View File

@ -1,21 +0,0 @@
#ifndef E_TABLE_RENDER_H
#define E_TABLE_RENDER_H
#include <libgnomeui/gnome-canvas.h>
struct ERenderContext {
ETableCol *etc;
int row;
int base_x, base_y;
GnomeCanvasItem *gnome_canvas_item;
GdkDrawable *drawable;
int drawable_width;
int drawable_height;
void *render_data;
void *closure;
};
void e_table_render_string (ERenderContext *ctxt);
#endif

View File

@ -1,111 +0,0 @@
/*
* e-table-model.c: a simple table model implementation that uses function
* pointers to simplify the creation of new, exotic and colorful tables in
* no time.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* (C) 1999 Helix Code, Inc.
*/
#include <config.h>
#include "e-table-simple.h"
#define PARENT_TYPE e_table_model_get_type()
static int
simple_column_count (ETableModel *etm)
{
ETableSimple *simple = (ETableSimple *)etm;
return simple->col_count (etm, simple->data);
}
static int
simple_row_count (ETableModel *etm)
{
ETableSimple *simple = (ETableSimple *)etm;
return simple->row_count (etm, simple->data);
}
static void *
simple_value_at (ETableModel *etm, int col, int row)
{
ETableSimple *simple = (ETableSimple *)etm;
return simple->value_at (etm, col, row, simple->data);
}
static void
simple_set_value_at (ETableModel *etm, int col, int row, const void *val)
{
ETableSimple *simple = (ETableSimple *)etm;
simple->set_value_at (etm, col, row, val, simple->data);
}
static gboolean
simple_is_cell_editable (ETableModel *etm, int col, int row)
{
ETableSimple *simple = (ETableSimple *)etm;
return simple->is_cell_editable (etm, col, row, simple->data);
}
static void
e_table_simple_class_init (GtkObjectClass *object_class)
{
ETableModelClass *model_class = (ETableModelClass *) object_class;
model_class->column_count = simple_column_count;
model_class->row_count = simple_row_count;
model_class->value_at = simple_value_at;
model_class->set_value_at = simple_set_value_at;
model_class->is_cell_editable = simple_is_cell_editable;
}
GtkType
e_table_simple_get_type (void)
{
static GtkType type = 0;
if (!type){
GtkTypeInfo info = {
"ETableSimple",
sizeof (ETableSimple),
sizeof (ETableSimpleClass),
(GtkClassInitFunc) e_table_simple_class_init,
(GtkObjectInitFunc) NULL,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
type = gtk_type_unique (PARENT_TYPE, &info);
}
return type;
}
ETableModel *
e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleRowCountFn row_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
void *data)
{
ETableSimple *et;
et = gtk_type_new (e_table_simple_get_type ());
et->col_count = col_count;
et->row_count = row_count;
et->value_at = value_at;
et->set_value_at = set_value_at;
et->is_cell_editable = is_cell_editable;
return (ETableModel *) et;
}

View File

@ -1,37 +0,0 @@
#ifndef _E_TABLE_SIMPLE_H_
#define _E_TABLE_SIMPLE_H_
#include "e-table-model.h"
typedef int (*ETableSimpleColumnCountFn) (ETableModel *etm, void *data);
typedef int (*ETableSimpleRowCountFn) (ETableModel *etm, void *data);
typedef void *(*ETableSimpleValueAtFn) (ETableModel *etm, int col, int row, void *data);
typedef void (*ETableSimpleSetValueAtFn) (ETableModel *etm, int col, int row, const void *val, void *data);
typedef gboolean (*ETableSimpleIsCellEditableFn) (ETableModel *etm, int col, int row, void *data);
typedef struct {
ETableModel parent;
ETableSimpleColumnCountFn col_count;
ETableSimpleRowCountFn row_count;
ETableSimpleValueAtFn value_at;
ETableSimpleSetValueAtFn set_value_at;
ETableSimpleIsCellEditableFn is_cell_editable;
void *data;
} ETableSimple;
typedef struct {
ETableModelClass parent_class;
} ETableSimpleClass;
GtkType e_table_simple_get_type (void);
ETableModel *e_table_simple_new (ETableSimpleColumnCountFn col_count,
ETableSimpleRowCountFn row_count,
ETableSimpleValueAtFn value_at,
ETableSimpleSetValueAtFn set_value_at,
ETableSimpleIsCellEditableFn is_cell_editable,
void *data);
#endif /* _E_TABLE_SIMPLE_H_ */

View File

@ -1,89 +0,0 @@
/*
* E-table-sorted.c: Implements a table that sorts another table
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* (C) 1999 Helix Code, Inc.
*/
#include <config.h>
#include <stdlib.h>
#include "e-util.h"
#include "e-table-sorted.h"
#define PARENT_TYPE E_TABLE_SUBSET_TYPE
static ETableModelClass *ets_parent_class;
static void
ets_class_init (GtkObjectClass *klass)
{
ets_parent_class = gtk_type_class (PARENT_TYPE);
}
E_MAKE_TYPE(e_table_sorted, "ETableSorted", ETableSorted, ets_class_init, NULL, PARENT_TYPE);
static ETableSorted *sort_ets;
static int
my_sort (const void *a, const void *b)
{
ETableModel *source = E_TABLE_SUBSET (sort_ets)->source;
const int *ia = (const int *) a;
const int *ib = (const int *) b;
void *va, *vb;
va = e_table_model_value_at (source, sort_ets->sort_col, *ia);
vb = e_table_model_value_at (source, sort_ets->sort_col, *ib);
return (*sort_ets->compare) (va, vb);
}
static void
do_sort (ETableSorted *ets)
{
ETableSubset *etss = E_TABLE_SUBSET (ets);
g_assert (sort_ets == NULL);
sort_ets = ets;
qsort (etss->map_table, etss->n_map, sizeof (unsigned int), my_sort);
sort_ets = NULL;
}
ETableModel *
e_table_sorted_new (ETableModel *source, int col, GCompareFunc compare)
{
ETableSorted *ets = gtk_type_new (E_TABLE_SORTED_TYPE);
ETableSubset *etss = E_TABLE_SUBSET (ets);
const int nvals = e_table_model_row_count (source);
int i;
if (e_table_subset_construct (etss, source, nvals) == NULL){
gtk_object_destroy (GTK_OBJECT (ets));
return NULL;
}
ets->compare = compare;
ets->sort_col = col;
/* Init */
for (i = 0; i < nvals; i++)
etss->map_table [i] = i;
do_sort (ets);
return (ETableModel *) ets;
}
void
e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare)
{
if (col == -1 || compare == NULL)
do_sort (ets);
else {
ets->sort_col = col;
ets->compare = compare;
do_sort (ets);
}
}

View File

@ -1,29 +0,0 @@
#ifndef _E_TABLE_SORTED_H_
#define _E_TABLE_SORTED_H_
#include <gtk/gtkobject.h>
#include "e-table-model.h"
#include "e-table-subset.h"
#define E_TABLE_SORTED_TYPE (e_table_sorted_get_type ())
#define E_TABLE_SORTED(o) (GTK_CHECK_CAST ((o), E_TABLE_SORTED_TYPE, ETableSorted))
#define E_TABLE_SORTED_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SORTED_TYPE, ETableSortedClass))
#define E_IS_TABLE_SORTED(o) (GTK_CHECK_TYPE ((o), E_TABLE_SORTED_TYPE))
#define E_IS_TABLE_SORTED_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SORTED_TYPE))
typedef struct {
ETableSubset base;
short sort_col;
GCompareFunc compare;
} ETableSorted;
typedef struct {
ETableSubset parent_class;
} ETableSortedClass;
GtkType e_table_sorted_get_type (void);
ETableModel *e_table_sorted_new (ETableModel *etm, int col, GCompareFunc compare);
void e_table_sorted_resort (ETableSorted *ets, int col, GCompareFunc compare);
#endif /* _E_TABLE_SORTED_H_ */

View File

@ -1,178 +0,0 @@
/*
* E-table-subset.c: Implements a table that contains a subset of another table.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* (C) 1999 Helix Code, Inc.
*/
#include <config.h>
#include <stdlib.h>
#include <gtk/gtksignal.h>
#include "e-util.h"
#include "e-table-subset.h"
#define PARENT_TYPE E_TABLE_MODEL_TYPE
static ETableModelClass *etss_parent_class;
static void
etss_destroy (GtkObject *object)
{
ETableSubset *etss = E_TABLE_SUBSET (object);
if (etss->source)
gtk_object_unref (GTK_OBJECT (etss->source));
if (etss->map_table)
free (etss->map_table);
GTK_OBJECT_CLASS (etss_parent_class)->destroy (object);
}
static int
etss_column_count (ETableModel *etm)
{
ETableSubset *etss = (ETableSubset *)etm;
return e_table_model_column_count (etss->source);
}
static int
etss_row_count (ETableModel *etm)
{
ETableSubset *etss = (ETableSubset *)etm;
return etss->n_map;
}
static void *
etss_value_at (ETableModel *etm, int col, int row)
{
ETableSubset *etss = (ETableSubset *)etm;
return e_table_model_value_at (etss->source, col, etss->map_table [row]);
}
static void
etss_set_value_at (ETableModel *etm, int col, int row, const void *val)
{
ETableSubset *etss = (ETableSubset *)etm;
return e_table_model_set_value_at (etss->source, col, etss->map_table [row], val);
}
static gboolean
etss_is_cell_editable (ETableModel *etm, int col, int row)
{
ETableSubset *etss = (ETableSubset *)etm;
return e_table_model_is_cell_editable (etss->source, col, etss->map_table [row]);
}
static void
etss_class_init (GtkObjectClass *klass)
{
ETableModelClass *table_class = (ETableModelClass *) klass;
etss_parent_class = gtk_type_class (PARENT_TYPE);
klass->destroy = etss_destroy;
table_class->column_count = etss_column_count;
table_class->row_count = etss_row_count;
table_class->value_at = etss_value_at;
table_class->set_value_at = etss_set_value_at;
table_class->is_cell_editable = etss_is_cell_editable;
}
E_MAKE_TYPE(e_table_subset, "ETableSubset", ETableSubset, etss_class_init, NULL, PARENT_TYPE);
static void
etss_proxy_model_changed (ETableModel *etm, ETableSubset *etss)
{
e_table_model_changed (E_TABLE_MODEL (etss));
}
static void
etss_proxy_model_row_changed (ETableModel *etm, int row, ETableSubset *etss)
{
const int n = etss->n_map;
const int * const map_table = etss->map_table;
int i;
for (i = 0; i < n; i++){
if (map_table [i] == row){
e_table_model_row_changed (E_TABLE_MODEL (etss), i);
return;
}
}
}
static void
etss_proxy_model_cell_changed (ETableModel *etm, int col, int row, ETableSubset *etss)
{
const int n = etss->n_map;
const int * const map_table = etss->map_table;
int i;
for (i = 0; i < n; i++){
if (map_table [i] == row){
e_table_model_cell_changed (E_TABLE_MODEL (etss), col, i);
return;
}
}
}
ETableModel *
e_table_subset_construct (ETableSubset *etss, ETableModel *source, int nvals)
{
unsigned int *buffer;
int i;
buffer = (unsigned int *) malloc (sizeof (unsigned int) * nvals);
if (buffer == NULL)
return NULL;
etss->map_table = buffer;
etss->n_map = nvals;
etss->source = source;
gtk_object_ref (GTK_OBJECT (source));
/* Init */
for (i = 0; i < nvals; i++)
etss->map_table [i] = i;
gtk_signal_connect (GTK_OBJECT (source), "model_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_changed), etss);
gtk_signal_connect (GTK_OBJECT (source), "model_row_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_row_changed), etss);
gtk_signal_connect (GTK_OBJECT (source), "model_cell_changed",
GTK_SIGNAL_FUNC (etss_proxy_model_cell_changed), etss);
return E_TABLE_MODEL (etss);
}
ETableModel *
e_table_subset_new (ETableModel *source, const int nvals)
{
ETableSubset *etss = gtk_type_new (E_TABLE_SUBSET_TYPE);
if (e_table_subset_construct (etss, source, nvals) == NULL){
gtk_object_destroy (GTK_OBJECT (etss));
return NULL;
}
return (ETableModel *) etss;
}
ETableModel *
e_table_subset_get_toplevel (ETableSubset *table)
{
g_return_val_if_fail (table != NULL, NULL);
g_return_val_if_fail (E_IS_TABLE_SUBSET (table), NULL);
if (E_IS_TABLE_SUBSET (table->source))
return e_table_subset_get_toplevel (E_TABLE_SUBSET (table->source));
else
return table->source;
}

View File

@ -1,32 +0,0 @@
#ifndef _E_TABLE_SUBSET_H_
#define _E_TABLE_SUBSET_H_
#include <gtk/gtkobject.h>
#include "e-table-model.h"
#define E_TABLE_SUBSET_TYPE (e_table_subset_get_type ())
#define E_TABLE_SUBSET(o) (GTK_CHECK_CAST ((o), E_TABLE_SUBSET_TYPE, ETableSubset))
#define E_TABLE_SUBSET_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_SUBSET_TYPE, ETableSubsetClass))
#define E_IS_TABLE_SUBSET(o) (GTK_CHECK_TYPE ((o), E_TABLE_SUBSET_TYPE))
#define E_IS_TABLE_SUBSET_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_SUBSET_TYPE))
typedef struct {
ETableModel base;
ETableModel *source;
int n_map;
int *map_table;
} ETableSubset;
typedef struct {
ETableModelClass parent_class;
} ETableSubsetClass;
GtkType e_table_subset_get_type (void);
ETableModel *e_table_subset_new (ETableModel *etm, int n_vals);
ETableModel *e_table_subset_construct (ETableSubset *ets, ETableModel *source, int nvals);
ETableModel *e_table_subset_get_toplevel (ETableSubset *table_model);
#endif /* _E_TABLE_SUBSET_H_ */

View File

@ -1,19 +0,0 @@
#ifndef _E_TABLE_TREE_H_
#define _E_TABLE_TREE_H_
typedef struct {
char *title;
union {
ETableModel *table;
GList *children;
} u;
guint expanded :1;
guint is_leaf :1;
} ETableGroup;
ETableGroup *e_table_group_new (const char *title, ETableModel *table);
ETableGroup *e_table_group_new_leaf (const char *title);
#endif /* _E_TABLE_TREE_H_ */

View File

@ -1,558 +0,0 @@
/*
* E-table-view.c: A graphical view of a Table.
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*
* Copyright 1999, Helix Code, Inc
*/
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <alloca.h>
#include <stdio.h>
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtksignal.h>
#include "e-table.h"
#include "e-util.h"
#include "e-table-header-item.h"
#include "e-table-subset.h"
#include "e-table-item.h"
#include "e-table-group.h"
#define COLUMN_HEADER_HEIGHT 16
#define TITLE_HEIGHT 16
#define GROUP_INDENT 10
#define PARENT_TYPE gtk_table_get_type ()
static GtkObjectClass *e_table_parent_class;
static void
et_destroy (GtkObject *object)
{
ETable *et = E_TABLE (object);
gtk_object_unref (GTK_OBJECT (et->model));
gtk_object_unref (GTK_OBJECT (et->full_header));
gtk_object_unref (GTK_OBJECT (et->header));
g_free (et->group_spec);
(*e_table_parent_class->destroy)(object);
}
static void
e_table_init (GtkObject *object)
{
ETable *e_table = E_TABLE (object);
e_table->draw_grid = 1;
e_table->draw_focus = 1;
e_table->spreadsheet = 1;
}
static ETableHeader *
e_table_make_header (ETable *e_table, ETableHeader *full_header, const char *cols)
{
ETableHeader *nh;
char *copy = alloca (strlen (cols) + 1);
char *p, *state;
const int max_cols = e_table_header_count (full_header);
nh = e_table_header_new ();
strcpy (copy, cols);
while ((p = strtok_r (copy, ",", &state)) != NULL){
int col = atoi (p);
copy = NULL;
if (col >= max_cols)
continue;
e_table_header_add_column (nh, e_table_header_get_column (full_header, col), -1);
}
return nh;
}
static void
header_canvas_size_alocate (GtkWidget *widget, GtkAllocation *alloc, ETable *e_table)
{
gnome_canvas_set_scroll_region (
GNOME_CANVAS (e_table->header_canvas),
0, 0, alloc->width, COLUMN_HEADER_HEIGHT);
}
static void
e_table_setup_header (ETable *e_table)
{
e_table->header_canvas = GNOME_CANVAS (gnome_canvas_new ());
gtk_widget_show (GTK_WIDGET (e_table->header_canvas));
e_table->header_item = gnome_canvas_item_new (
gnome_canvas_root (e_table->header_canvas),
e_table_header_item_get_type (),
"ETableHeader", e_table->header,
"x", 0,
"y", 0,
NULL);
gtk_signal_connect (
GTK_OBJECT (e_table->header_canvas), "size_allocate",
GTK_SIGNAL_FUNC (header_canvas_size_alocate), e_table);
gtk_widget_set_usize (GTK_WIDGET (e_table->header_canvas), -1, COLUMN_HEADER_HEIGHT);
gtk_table_attach (
GTK_TABLE (e_table), GTK_WIDGET (e_table->header_canvas),
0, 1, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
}
typedef struct {
void *value;
GArray *array;
} group_key_t;
static GArray *
e_table_create_groups (ETableModel *etm, int key_col, GCompareFunc comp)
{
GArray *groups;
const int rows = e_table_model_row_count (etm);
int row, i;
groups = g_array_new (FALSE, FALSE, sizeof (group_key_t));
for (row = 0; row < rows; row++){
void *val = e_table_model_value_at (etm, key_col, row);
const int n_groups = groups->len;
/*
* Should replace this with a bsearch later
*/
for (i = 0; i < n_groups; i++){
group_key_t *g = &g_array_index (groups, group_key_t, i);
if ((*comp) (g->value, val)){
g_array_append_val (g->array, row);
break;
}
}
if (i != n_groups)
continue;
/*
* We need to create a new group
*/
{
group_key_t gk;
gk.value = val;
gk.array = g_array_new (FALSE, FALSE, sizeof (int));
g_array_append_val (gk.array, row);
g_array_append_val (groups, gk);
}
}
return groups;
}
static void
e_table_destroy_groups (GArray *groups)
{
const int n = groups->len;
int i;
for (i = 0; i < n; i++){
group_key_t *g = &g_array_index (groups, group_key_t, i);
g_array_free (g->array, TRUE);
}
g_array_free (groups, TRUE);
}
static ETableModel **
e_table_make_subtables (ETableModel *model, GArray *groups)
{
const int n_groups = groups->len;
ETableModel **tables;
int i;
tables = g_new (ETableModel *, n_groups+1);
for (i = 0; i < n_groups; i++){
group_key_t *g = &g_array_index (groups, group_key_t, i);
const int sub_size = g->array->len;
ETableSubset *ss;
int j;
tables [i] = e_table_subset_new (model, sub_size);
ss = E_TABLE_SUBSET (tables [i]);
for (j = 0; j < sub_size; j++)
ss->map_table [j] = g_array_index (g->array, int, j);
}
tables [i] = NULL;
return (ETableModel **) tables;
}
typedef struct _Node Node;
struct _Node {
Node *parent;
GnomeCanvasItem *item;
ETableModel *table_model;
GSList *children;
guint is_leaf:1;
};
static Node *
leaf_new (GnomeCanvasItem *table_item, ETableModel *table_model, Node *parent)
{
Node *node = g_new (Node, 1);
g_assert (table_item != NULL);
g_assert (table_model != NULL);
g_assert (parent != NULL);
node->item = table_item;
node->parent = parent;
node->table_model = table_model;
node->is_leaf = 1;
g_assert (!parent->is_leaf);
parent->children = g_slist_append (parent->children, node);
e_table_group_add (E_TABLE_GROUP (parent->item), table_item);
return node;
}
static Node *
node_new (GnomeCanvasItem *group_item, ETableModel *table_model, Node *parent)
{
Node *node = g_new (Node, 1);
g_assert (table_model != NULL);
node->children = NULL;
node->item = group_item;
node->parent = parent;
node->table_model = table_model;
node->is_leaf = 0;
if (parent){
parent->children = g_slist_append (parent->children, node);
e_table_group_add (E_TABLE_GROUP (parent->item), group_item);
}
return node;
}
static Node *
e_table_create_leaf (ETable *e_table, ETableModel *etm, Node *parent)
{
GnomeCanvasItem *table_item;
static double last_y;
Node *leaf;
table_item = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (parent->item),
e_table_item_get_type (),
"ETableHeader", e_table->header,
"ETableModel", etm,
"drawgrid", e_table->draw_grid,
"drawfocus", e_table->draw_focus,
"spreadsheet", e_table->spreadsheet,
NULL);
leaf = leaf_new (table_item, etm, parent);
return leaf;
}
static int
leaf_height (Node *leaf)
{
const GnomeCanvasItem *item = leaf->item;
return item->y2 - item->y1;
}
static int
leaf_event (GnomeCanvasItem *item, GdkEvent *event)
{
static int last_x = -1;
static int last_y = -1;
if (event->type == GDK_BUTTON_PRESS){
last_x = event->button.x;
last_y = event->button.y;
} else if (event->type == GDK_BUTTON_RELEASE){
last_x = -1;
last_y = -1;
} else if (event->type == GDK_MOTION_NOTIFY){
if (last_x == -1)
return FALSE;
gnome_canvas_item_move (item, event->motion.x - last_x, event->motion.y - last_y);
last_x = event->motion.x;
last_y = event->motion.y;
} else
return FALSE;
return TRUE;
}
static Node *
e_table_create_nodes (ETable *e_table, ETableModel *model, ETableHeader *header,
GnomeCanvasGroup *root, Node *parent, int *groups_list)
{
GArray *groups;
ETableModel **tables;
ETableCol *ecol;
int key_col, i;
GnomeCanvasItem *group_item;
Node *group;
key_col = *groups_list;
g_assert (key_col != -1);
/*
* Create groups
*/
ecol = e_table_header_get_column (header, key_col);
g_assert (ecol != NULL);
groups = e_table_create_groups (model, key_col, ecol->compare);
tables = e_table_make_subtables (e_table->model, groups);
e_table_destroy_groups (groups);
group_item = e_table_group_new (root, ecol, TRUE, parent == NULL);
group = node_new (group_item, model, parent);
for (i = 0; tables [i] != NULL; i++){
Node *node;
/*
* Leafs
*/
if (groups_list [1] == -1){
GnomeCanvasItem *item_leaf_header;
Node *leaf_header;
item_leaf_header = e_table_group_new (
GNOME_CANVAS_GROUP (group_item), ecol, TRUE, FALSE);
leaf_header = node_new (item_leaf_header, tables [i], group);
e_table_create_leaf (e_table, tables [i], leaf_header);
} else {
e_table_create_nodes (
e_table, tables [i], header, GNOME_CANVAS_GROUP (group_item),
group, &groups_list [1]);
}
}
return group;
}
static int *
group_spec_to_desc (const char *group_spec)
{
int a_size = 10;
int *elements;
char *p, *copy, *follow;
int n_elements = 0;
if (group_spec == NULL)
return NULL;
elements = g_new (int, a_size);
copy = alloca (strlen (group_spec) + 1);
strcpy (copy, group_spec);
while ((p = strtok_r (copy, ",", &follow)) != NULL){
elements [n_elements] = atoi (p);
++n_elements;
if (n_elements+1 == a_size){
int *new_e;
n_elements += 10;
new_e = g_renew (int, elements, n_elements);
if (new_e == NULL){
g_free (elements);
return NULL;
}
elements = new_e;
}
copy = NULL;
}
/* Tag end */
elements [n_elements] = -1;
return elements;
}
/*
* The ETableCanvas object is just used to enable us to
* hook up to the realize/unrealize phases of the canvas
* initialization (as laying out the subtables requires us to
* know the actual size of the subtables we are inserting
*/
#define E_TABLE_CANVAS_PARENT_TYPE gnome_canvas_get_type ()
typedef struct {
GnomeCanvas base;
ETable *e_table;
} ETableCanvas;
typedef struct {
GnomeCanvasClass base_class;
} ETableCanvasClass;
static GnomeCanvasClass *e_table_canvas_parent_class;
static void
e_table_canvas_realize (GtkWidget *widget)
{
ETableCanvas *e_table_canvas = (ETableCanvas *) widget;
ETable *e_table = e_table_canvas->e_table;
int *groups;
Node *leaf;
GTK_WIDGET_CLASS (e_table_canvas_parent_class)->realize (widget);
groups = group_spec_to_desc (e_table->group_spec);
e_table->root = gnome_canvas_item_new (
GNOME_CANVAS_GROUP (e_table->table_canvas->root),
gnome_canvas_group_get_type (),
"x", 0.0,
"y", 0.0,
NULL);
leaf = e_table_create_nodes (
e_table, e_table->model,
e_table->header, GNOME_CANVAS_GROUP (e_table->root), 0, groups);
gnome_canvas_set_scroll_region (
GNOME_CANVAS (e_table_canvas),
0, 0,
e_table_header_total_width (e_table->header) + 200,
leaf_height (leaf));
if (groups)
g_free (groups);
}
static void
e_table_canvas_unrealize (GtkWidget *widget)
{
ETableCanvas *e_table_canvas = (ETableCanvas *) widget;
ETable *e_table = e_table_canvas->e_table;
gtk_object_destroy (GTK_OBJECT (e_table->root));
e_table->root = NULL;
GTK_WIDGET_CLASS (e_table_canvas_parent_class)->unrealize (widget);
}
static void
e_table_canvas_class_init (GtkObjectClass *object_class)
{
GtkWidgetClass *widget_class = (GtkWidgetClass *) object_class;
widget_class->realize = e_table_canvas_realize;
widget_class->unrealize = e_table_canvas_unrealize;
e_table_canvas_parent_class = gtk_type_class (E_TABLE_CANVAS_PARENT_TYPE);
}
static void
e_table_canvas_init (GtkObject *canvas)
{
GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
}
GtkType e_table_canvas_get_type (void);
E_MAKE_TYPE (e_table_canvas, "ETableCanvas", ETableCanvas, e_table_canvas_class_init,
e_table_canvas_init, E_TABLE_CANVAS_PARENT_TYPE);
static GnomeCanvas *
e_table_canvas_new (ETable *e_table)
{
ETableCanvas *e_table_canvas;
e_table_canvas = gtk_type_new (e_table_canvas_get_type ());
e_table_canvas->e_table = e_table;
return GNOME_CANVAS (e_table_canvas);
}
static void
e_table_setup_table (ETable *e_table)
{
e_table->table_canvas = e_table_canvas_new (e_table);
gtk_widget_show (GTK_WIDGET (e_table->table_canvas));
gtk_table_attach (
GTK_TABLE (e_table), GTK_WIDGET (e_table->table_canvas),
0, 1, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
}
void
e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
const char *cols_spec, const char *group_spec)
{
GTK_TABLE (e_table)->homogeneous = FALSE;
gtk_table_resize (GTK_TABLE (e_table), 1, 2);
e_table->full_header = full_header;
gtk_object_ref (GTK_OBJECT (full_header));
e_table->model = etm;
gtk_object_ref (GTK_OBJECT (etm));
e_table->header = e_table_make_header (e_table, full_header, cols_spec);
e_table_setup_header (e_table);
e_table_setup_table (e_table);
e_table->group_spec = g_strdup (group_spec);
}
GtkWidget *
e_table_new (ETableHeader *full_header, ETableModel *etm, const char *cols_spec, const char *group_spec)
{
ETable *e_table;
e_table = gtk_type_new (e_table_get_type ());
e_table_construct (e_table, full_header, etm, cols_spec, group_spec);
return (GtkWidget *) e_table;
}
static void
e_table_class_init (GtkObjectClass *object_class)
{
e_table_parent_class = gtk_type_class (PARENT_TYPE);
object_class->destroy = et_destroy;
}
E_MAKE_TYPE(e_table, "ETable", ETable, e_table_class_init, e_table_init, PARENT_TYPE);

View File

@ -1,48 +0,0 @@
#ifndef _E_TABLE_H_
#define _E_TABLE_H_
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtktable.h>
#include "e-table-model.h"
#include "e-table-header.h"
BEGIN_GNOME_DECLS
#define E_TABLE_TYPE (e_table_get_type ())
#define E_TABLE(o) (GTK_CHECK_CAST ((o), E_TABLE_TYPE, ETable))
#define E_TABLE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_TABLE_TYPE, ETableClass))
#define E_IS_TABLE(o) (GTK_CHECK_TYPE ((o), E_TABLE_TYPE))
#define E_IS_TABLE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TABLE_TYPE))
typedef struct {
GtkTable parent;
ETableModel *model;
ETableHeader *full_header, *header;
GnomeCanvas *header_canvas, *table_canvas;
GnomeCanvasItem *header_item, *root;
guint draw_grid:1;
guint draw_focus:1;
guint spreadsheet:1;
char *group_spec;
} ETable;
typedef struct {
GtkTableClass parent_class;
} ETableClass;
GtkType e_table_get_type (void);
void e_table_construct (ETable *e_table, ETableHeader *full_header, ETableModel *etm,
const char *cols_spec, const char *group_spec);
GtkWidget *e_table_new (ETableHeader *full_header, ETableModel *etm,
const char *cols_spec, const char *group_spec);
END_GNOME_DECLS
#endif /* _E_TABLE_H_ */

View File

@ -1,16 +1,11 @@
SUBDIRS =
meeting-time-sel
INCLUDES = \
-I$(top_srcdir)/camel \
-I$(top_builddir)/camel \
$(GNOME_INCLUDEDIR)
$(GNOME_INCLUDEDIR) \
-I$(top_srcdir)/e-util
noinst_LIBRARIES = \
libevolutionwidgets.a
libetable.a
libevolutionwidgets_a_SOURCES = \
libetable_a_SOURCES = \
e-cell.c \
e-cell.h \
e-cell-checkbox.c \
@ -19,8 +14,6 @@ libevolutionwidgets_a_SOURCES = \
e-cell-text.h \
e-cell-toggle.c \
e-cell-toggle.h \
e-cursors.c \
e-cursors.h \
e-table.c \
e-table.h \
e-table-col.c \
@ -51,9 +44,10 @@ table_test_SOURCES = \
test-cols.c \
table-test.c
table_test_LDADD = \
$(EXTRA_GNOME_LIBS) \
libevolutionwidgets.a
table_test_LDADD = \
$(EXTRA_GNOME_LIBS) \
libetable.a \
$(top_builddir)/e-util/libeutil.a
table_test_LDFLAGS = `gnome-config --libs gdk_pixbuf`

View File

@ -14,7 +14,7 @@
#include <gdk/gdkkeysyms.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-cell-checkbox.h"
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-item.h"
#include "check-empty.xpm"

View File

@ -15,7 +15,7 @@
#include <libgnomeui/gnome-canvas.h>
#include <stdio.h>
#include "e-cell-text.h"
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()

View File

@ -14,7 +14,7 @@
#include <gdk/gdkkeysyms.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-cell-toggle.h"
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()

View File

@ -8,7 +8,7 @@
*/
#include <config.h>
#include "e-cell.h"
#include "e-util.h"
#include <e-util/e-util.h>
#define PARENT_TYPE gtk_object_get_type()

View File

@ -10,7 +10,7 @@
#include <gtk/gtkobject.h>
#include <gtk/gtksignal.h>
#include "e-table-col.h"
#include "e-util.h"
#include <e-util/e-util.h>
#define PARENT_TYPE (gtk_object_get_type ())

View File

@ -12,7 +12,7 @@
#include "e-table-group.h"
#include "e-table-item.h"
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include "e-util.h"
#include <e-util/e-util.h>
#define TITLE_HEIGHT 16
#define GROUP_INDENT 10

View File

@ -8,7 +8,7 @@
*/
#include <config.h>
#include <stdlib.h>
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-sorted.h"
#define PARENT_TYPE E_TABLE_SUBSET_TYPE

View File

@ -9,7 +9,7 @@
#include <config.h>
#include <stdlib.h>
#include <gtk/gtksignal.h>
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-subset.h"
#define PARENT_TYPE E_TABLE_MODEL_TYPE

View File

@ -14,8 +14,8 @@
#include <stdio.h>
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtksignal.h>
#include <e-util/e-util.h>
#include "e-table.h"
#include "e-util.h"
#include "e-table-header-item.h"
#include "e-table-subset.h"
#include "e-table-item.h"

View File

@ -1,24 +0,0 @@
#ifndef _E_UTIL_H_
#define _E_UTIL_H_
#define E_MAKE_TYPE(l,str,t,ci,i,parent) \
GtkType l##_get_type(void)\
{\
static GtkType type = 0;\
if (!type){\
GtkTypeInfo info = {\
str,\
sizeof (t),\
sizeof (t##Class),\
(GtkClassInitFunc) ci,\
(GtkObjectInitFunc) i,\
NULL, /* reserved 1 */\
NULL, /* reserved 2 */\
(GtkClassInitFunc) NULL\
};\
type = gtk_type_unique (parent, &info);\
}\
return type;\
}\
#endif /* _E_UTIL_H_ */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,22 +0,0 @@
/* XPM */
static char * remove_col_xpm[] = {
"16 16 3 1",
" c None",
". c #000000",
"+ c #FF0000",
"... ...",
".++. .++.",
".+++. .+++.",
" .+++. .+++. ",
" .+++. .+++. ",
" .+++..+++. ",
" .++++++. ",
" .++++. ",
" .++++. ",
" .++++++. ",
" .+++..+++. ",
" .+++. .+++. ",
" .+++. .+++. ",
".+++. .+++.",
".++. .++.",
"... ..."};

View File

@ -1,11 +0,0 @@
Col1 Col2 Address Title Dorks
c1.a c2.a a.a tit-1 DorkA
c1.b c2.b a.b tit-2 DDork
c1.c c2.c a.c tit-1 DorkB
c1.d c2.d a.d tit-2 ADork
c1.e c2.e a.e tit-1 DorkC
c1.f c2.f a.f tit-2 UDork
c1.g c2.g a.g tit-3 Dork---
j k k tit-1 DorkA

View File

@ -0,0 +1,30 @@
noinst_LIBRARIES = libshortcut-bar.a
noinst_PROGRAMS = test-shortcut-bar
INCLUDES = \
-DEVOLUTION_VERSION=\""$(VERSION)"\" \
$(EXTRA_GNOME_CFLAGS)
libshortcut_bar_a_SOURCES = \
e-clipped-label.c \
e-clipped-label.h \
e-group-bar.c \
e-group-bar.h \
e-icon-bar-bg-item.c \
e-icon-bar-bg-item.h \
e-icon-bar-text-item.c \
e-icon-bar-text-item.h \
e-icon-bar.c \
e-icon-bar.h \
e-shortcut-bar.c \
e-shortcut-bar.h \
e-vscrolled-bar.c \
e-vscrolled-bar.h
test_shortcut_bar_SOURCES = \
test-shortcut-bar.c
test_shortcut_bar_LDADD = \
./libshortcut-bar.a \
$(EXTRA_GNOME_LIBS) \

View File

@ -0,0 +1,361 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* This is similar to GtkLabel but clips itself and displays '...' if it
* can't fit inside its allocated area. The intended use is for inside buttons
* that are a fixed size. The GtkLabel would normally display only the middle
* part of the text, which doesn't look very good. This only supports one line
* of text (so no wrapping/justification), without underlined characters.
*/
#include <math.h>
#include <gdk/gdki18n.h>
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
#include "e-clipped-label.h"
static void e_clipped_label_class_init (EClippedLabelClass *class);
static void e_clipped_label_init (EClippedLabel *label);
static void e_clipped_label_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void e_clipped_label_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static gint e_clipped_label_expose (GtkWidget *widget,
GdkEventExpose *event);
static void e_clipped_label_recalc_chars_displayed (EClippedLabel *label);
static GtkMiscClass *parent_class;
/* This is the string to draw when the label is clipped, e.g. '...'. */
static gchar *e_clipped_label_ellipsis;
/* Flags used in chars_displayed field. Must be negative. */
#define E_CLIPPED_LABEL_NEED_RECALC -1
#define E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL -2
GtkType
e_clipped_label_get_type (void)
{
static GtkType e_clipped_label_type = 0;
if (!e_clipped_label_type){
GtkTypeInfo e_clipped_label_info = {
"EClippedLabel",
sizeof (EClippedLabel),
sizeof (EClippedLabelClass),
(GtkClassInitFunc) e_clipped_label_class_init,
(GtkObjectInitFunc) e_clipped_label_init,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
parent_class = gtk_type_class (GTK_TYPE_MISC);
e_clipped_label_type = gtk_type_unique (GTK_TYPE_MISC,
&e_clipped_label_info);
}
return e_clipped_label_type;
}
static void
e_clipped_label_class_init (EClippedLabelClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
/* Method override */
widget_class->size_request = e_clipped_label_size_request;
widget_class->size_allocate = e_clipped_label_size_allocate;
widget_class->expose_event = e_clipped_label_expose;
e_clipped_label_ellipsis = _("...");
}
static void
e_clipped_label_init (EClippedLabel *label)
{
GTK_WIDGET_SET_FLAGS (label, GTK_NO_WINDOW);
label->label = NULL;
label->label_wc = NULL;
label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC;
}
/**
* e_clipped_label_new:
*
* @text: The label text.
* @Returns: A new #EClippedLabel.
*
* Creates a new #EClippedLabel with the given text.
**/
GtkWidget *
e_clipped_label_new (const gchar *text)
{
GtkWidget *label;
label = GTK_WIDGET (gtk_type_new (e_clipped_label_get_type ()));
if (text && *text)
e_clipped_label_set_text (E_CLIPPED_LABEL (label), text);
return label;
}
static void
e_clipped_label_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
EClippedLabel *label;
GdkFont *font;
g_return_if_fail (E_IS_CLIPPED_LABEL (widget));
g_return_if_fail (requisition != NULL);
label = E_CLIPPED_LABEL (widget);
font = widget->style->font;
requisition->width = 0;
requisition->height = font->ascent + font->descent
+ 2 * GTK_MISC (widget)->ypad;
}
static void
e_clipped_label_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
EClippedLabel *label;
label = E_CLIPPED_LABEL (widget);
widget->allocation = *allocation;
/* Flag that we need to recalculate how many characters to display. */
label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC;
}
static gint
e_clipped_label_expose (GtkWidget *widget,
GdkEventExpose *event)
{
EClippedLabel *label;
GtkMisc *misc;
gint x, y;
GdkFont *font;
gchar *tmp_str, tmp_ch;
g_return_val_if_fail (E_IS_CLIPPED_LABEL (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
label = E_CLIPPED_LABEL (widget);
misc = GTK_MISC (widget);
font = widget->style->font;
/* If the label isn't visible or has no text, just return. */
if (!GTK_WIDGET_VISIBLE (widget) || !GTK_WIDGET_MAPPED (widget)
|| !label->label || (*label->label == '\0'))
return TRUE;
/* Recalculate the number of characters displayed, if necessary. */
if (label->chars_displayed == E_CLIPPED_LABEL_NEED_RECALC)
e_clipped_label_recalc_chars_displayed (label);
/*
* GC Clipping
*/
gdk_gc_set_clip_rectangle (widget->style->white_gc,
&event->area);
gdk_gc_set_clip_rectangle (widget->style->fg_gc[widget->state],
&event->area);
y = floor (widget->allocation.y + (gint)misc->ypad
+ (((gint)widget->allocation.height - 2 * (gint)misc->ypad
- (gint)font->ascent - font->descent)
* misc->yalign) + 0.5) + font->ascent;
if (label->chars_displayed == E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL) {
x = floor (widget->allocation.x + (gint)misc->xpad
+ (((gint)widget->allocation.width -
(gint)label->label_width - 2 * (gint)misc->xpad)
* misc->xalign) + 0.5);
gtk_paint_string (widget->style, widget->window, widget->state,
&event->area, widget, "label",
x, y, label->label);
} else {
x = widget->allocation.x + (gint)misc->xpad;
tmp_ch = label->label_wc[label->chars_displayed];
label->label_wc[label->chars_displayed] = '\0';
tmp_str = gdk_wcstombs (label->label_wc);
if (tmp_str) {
gtk_paint_string (widget->style, widget->window,
widget->state, &event->area,
widget, "label",
x, y, tmp_str);
g_free (tmp_str);
}
label->label_wc[label->chars_displayed] = tmp_ch;
x = widget->allocation.x + (gint)misc->xpad
+ label->ellipsis_x;
gtk_paint_string (widget->style, widget->window, widget->state,
&event->area, widget, "label",
x, y, e_clipped_label_ellipsis);
}
gdk_gc_set_clip_mask (widget->style->white_gc, NULL);
gdk_gc_set_clip_mask (widget->style->fg_gc[widget->state], NULL);
return TRUE;
}
/**
* e_clipped_label_get_text:
*
* @label: An #EClippedLabel.
* @Return: The label text.
*
* Returns the label text, or NULL.
**/
gchar*
e_clipped_label_get_text (EClippedLabel *label)
{
g_return_val_if_fail (E_IS_CLIPPED_LABEL (label), NULL);
return label->label;
}
/**
* e_clipped_label_set_text:
*
* @label: An #EClippedLabel.
* @text: The new label text.
*
* Sets the label text.
**/
void
e_clipped_label_set_text (EClippedLabel *label,
const gchar *text)
{
gint len;
g_return_if_fail (E_IS_CLIPPED_LABEL (label));
if (label->label != text || !label->label || !text
|| strcmp (label->label, text)) {
g_free (label->label);
g_free (label->label_wc);
label->label = NULL;
label->label_wc = NULL;
if (text) {
label->label = g_strdup (text);
len = strlen (text);
label->label_wc = g_new (GdkWChar, len + 1);
label->wc_len = gdk_mbstowcs (label->label_wc,
label->label, len + 1);
label->label_wc[label->wc_len] = '\0';
}
/* Reset the number of characters displayed, so it is
recalculated when needed. */
label->chars_displayed = E_CLIPPED_LABEL_NEED_RECALC;
/* We don't queue a resize, since the label should not affect
the widget size, but we queue a draw. */
gtk_widget_queue_draw (GTK_WIDGET (label));
}
}
static void
e_clipped_label_recalc_chars_displayed (EClippedLabel *label)
{
GdkFont *font;
gint max_width, width, ch, last_width;
font = GTK_WIDGET (label)->style->font;
max_width = GTK_WIDGET (label)->allocation.width
- 2 * GTK_MISC (label)->xpad;
if (!label->label) {
label->chars_displayed = 0;
return;
}
/* See if the entire label fits in the allocated width. */
label->label_width = gdk_string_width (font, label->label);
if (label->label_width <= max_width) {
label->chars_displayed = E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL;
return;
}
/* Calculate the width of the ellipsis string. */
max_width -= gdk_string_measure (font, e_clipped_label_ellipsis);
if (max_width <= 0) {
label->chars_displayed = 0;
label->ellipsis_x = 0;
return;
}
/* Step through the wide-char label, adding on the widths of the
characters, until we can't fit any more in. */
width = last_width = 0;
for (ch = 0; ch < label->wc_len; ch++) {
width += gdk_char_width_wc (font, label->label_wc[ch]);
if (width > max_width) {
label->chars_displayed = ch;
label->ellipsis_x = last_width;
return;
}
last_width = width;
}
g_warning ("Clipped label width not exceeded as expected");
label->chars_displayed = E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL;
}

View File

@ -0,0 +1,90 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* This is similar to GtkLabel but clips itself and displays '...' if it
* can't fit inside its allocated area. The intended use is for inside buttons
* that are a fixed size. The GtkLabel would normally display only the middle
* part of the text, which doesn't look very good. This only supports one line
* of text (so no wrapping/justification), without underlined characters.
*/
#ifndef _E_CLIPPED_LABEL_H_
#define _E_CLIPPED_LABEL_H_
#include <gtk/gtkmisc.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define E_CLIPPED_LABEL(obj) GTK_CHECK_CAST (obj, e_clipped_label_get_type (), EClippedLabel)
#define E_CLIPPED_LABEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_clipped_label_get_type (), EClippedLabelClass)
#define E_IS_CLIPPED_LABEL(obj) GTK_CHECK_TYPE (obj, e_clipped_label_get_type ())
typedef struct _EClippedLabel EClippedLabel;
typedef struct _EClippedLabelClass EClippedLabelClass;
struct _EClippedLabel
{
GtkMisc misc;
gchar *label;
GdkWChar *label_wc;
/* This is the number of wide characters in the label. */
gint wc_len;
/* This is the width of the entire label string, in pixels. */
gint label_width;
/* This is the number of characters we can fit in, or
E_CLIPPED_LABEL_NEED_RECALC if it needs to be recalculated, or
E_CLIPPED_LABEL_SHOW_ENTIRE_LABEL to show the entire label. */
gint chars_displayed;
/* This is the x position to display the ellipsis string, e.g. '...',
relative to the start of the label. */
gint ellipsis_x;
};
struct _EClippedLabelClass
{
GtkMiscClass parent_class;
};
GtkType e_clipped_label_get_type (void);
GtkWidget* e_clipped_label_new (const gchar *text);
gchar* e_clipped_label_get_text (EClippedLabel *label);
void e_clipped_label_set_text (EClippedLabel *label,
const gchar *text);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_CLIPPED_LABEL_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,171 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#ifndef _E_GROUP_BAR_H_
#define _E_GROUP_BAR_H_
#include <gtk/gtkcontainer.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* EGroupBar displays a vertical bar with a number of Groups, which are viewed
* one at a time by selecting the Group's button. When a different Group is
* selected, it slides into view, and the old Group slides out.
* It is typically used on the left of the main application window so users
* can easily access particular features.
*
* It is implemented like GtkNotebook, i.e. the main widgets are the children
* of the EGroupBar and the button widgets are treated specially like the
* GtkNotebook tab labels.
*/
/* This contains information on one item. */
typedef struct _EGroupBarChild EGroupBarChild;
struct _EGroupBarChild
{
/* This is the button used to select the group, and the window we use
to move it around easily. */
GtkWidget *button;
GdkWindow *button_window;
gint button_height;
/* This is the child widget, which can be any widget added by the
application, and the window we use to move it around easily. */
GtkWidget *child;
GdkWindow *child_window;
/* These are TRUE if we are currently animating the windows. */
gboolean button_window_in_animation;
gboolean child_window_in_animation;
/* These are the target y positions that the windows should eventually
move to, used for animation. If we get a size_allocate we just
update these and the animation can continue as normal.
When a child window reaches its target position, it is unmapped if
if it is not the current group (i.e. it has slid off screen). */
gint button_window_target_y;
gint child_window_target_y;
};
#define E_GROUP_BAR(obj) GTK_CHECK_CAST (obj, e_group_bar_get_type (), EGroupBar)
#define E_GROUP_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_group_bar_get_type (), EGroupBarClass)
#define E_IS_GROUP_BAR(obj) GTK_CHECK_TYPE (obj, e_group_bar_get_type ())
typedef struct _EGroupBar EGroupBar;
typedef struct _EGroupBarClass EGroupBarClass;
struct _EGroupBar
{
GtkContainer container;
/* This is an array of EGroupBarChild elements. */
GArray *children;
/* This is the group currently shown. */
gint current_group_num;
/* This is TRUE if all the buttons are allocated the same height. */
gboolean buttons_homogeneous;
/* This is the biggest requested height of all the buttons, which we
use for all buttons when buttons_homogeneous is set. */
gint max_button_height;
/* This is the height of all the child windows & widgets. */
gint child_height;
/* The id of the source function for animation timeouts. If this is
not 0 then we are in the middle of an animation. */
guint animation_timeout_id;
/* The id of the source function for automatically showing groups when
the user drags over the group button, and the group to show. */
guint auto_show_timeout_id;
gint auto_show_group_num;
};
struct _EGroupBarClass
{
GtkContainerClass parent_class;
};
GtkType e_group_bar_get_type (void);
GtkWidget* e_group_bar_new (void);
/*
* Insertion, reordering and deletion of items.
*/
/* Adds a new group at the given position. If position is -1 it adds it as
the last group. It returns the group number. */
gint e_group_bar_add_group (EGroupBar *group_bar,
GtkWidget *child,
GtkWidget *button,
gint position);
void e_group_bar_reorder_group (EGroupBar *group_bar,
gint group_num,
gint new_position);
void e_group_bar_remove_group (EGroupBar *group_bar,
gint group_num);
/*
* Getting & setting the current group.
*/
gint e_group_bar_get_current_group_num (EGroupBar *group_bar);
void e_group_bar_set_current_group_num (EGroupBar *group_bar,
gint group_num);
/*
* Getting groups and group numbers.
*/
GtkWidget* e_group_bar_get_nth_group (EGroupBar *group_bar,
gint group_num);
gint e_group_bar_get_group_num (EGroupBar *group_bar,
GtkWidget *child);
/*
* Setting the group button label.
*/
void e_group_bar_set_group_button_label (EGroupBar *group_bar,
gint group_num,
GtkWidget *label);
/*
* Getting & setting the EGroupBar options.
*/
gboolean e_group_bar_get_buttons_homogeneous (EGroupBar *group_bar);
void e_group_bar_set_buttons_homogeneous (EGroupBar *group_bar,
gboolean homogeneous);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_GROUP_BAR_H_ */

View File

@ -0,0 +1,361 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* EIconBarBgItem - A GnomeCanvasItem which covers the entire EIconBar.
* It paints the rectangles around items when the mouse moves over them, and
* the lines between items when dragging.
*/
#include "e-icon-bar-bg-item.h"
#include "e-icon-bar.h"
/* This is the size of the border around the icons, for the shadow. */
#define E_ICON_BAR_LARGE_ICON_SHADOW_BORDER 2
#define E_ICON_BAR_SMALL_ICON_SHADOW_BORDER 2
/* These are for the horzontal bar when dragging. */
#define E_ICON_BAR_BG_ITEM_BAR_HEIGHT 1
#define E_ICON_BAR_BG_ITEM_BAR_OFFSET 2
#define E_ICON_BAR_BG_ITEM_LARGE_ARROW_HEIGHT 8
#define E_ICON_BAR_BG_ITEM_SMALL_ARROW_HEIGHT 4
static void e_icon_bar_bg_item_class_init (EIconBarBgItemClass *class);
static void e_icon_bar_bg_item_init (EIconBarBgItem *ibitem);
static void e_icon_bar_bg_item_set_arg (GtkObject *o, GtkArg *arg,
guint arg_id);
static void e_icon_bar_bg_item_update (GnomeCanvasItem *item,
double *affine,
ArtSVP *clip_path, int flags);
static void e_icon_bar_bg_item_draw (GnomeCanvasItem *item,
GdkDrawable *drawable,
int x, int y,
int width, int height);
static double e_icon_bar_bg_item_point (GnomeCanvasItem *item,
double x, double y,
int cx, int cy,
GnomeCanvasItem **actual_item);
static gint e_icon_bar_bg_item_event (GnomeCanvasItem *item,
GdkEvent *event);
static gint e_icon_bar_bg_item_button_press (EIconBarBgItem *ibitem,
GdkEvent *event);
static gint e_icon_bar_bg_item_button_release (EIconBarBgItem *ibitem,
GdkEvent *event);
static gint e_icon_bar_bg_item_motion_notify (EIconBarBgItem *ibitem,
GdkEvent *event);
static GnomeCanvasItemClass *parent_class;
/* The arguments we take */
enum {
ARG_0,
ARG_ICON_BAR
};
GtkType
e_icon_bar_bg_item_get_type (void)
{
static GtkType e_icon_bar_bg_item_type = 0;
if (!e_icon_bar_bg_item_type) {
GtkTypeInfo e_icon_bar_bg_item_info = {
"EIconBarBgItem",
sizeof (EIconBarBgItem),
sizeof (EIconBarBgItemClass),
(GtkClassInitFunc) e_icon_bar_bg_item_class_init,
(GtkObjectInitFunc) e_icon_bar_bg_item_init,
NULL, /* reserved_1 */
NULL, /* reserved_2 */
(GtkClassInitFunc) NULL
};
e_icon_bar_bg_item_type = gtk_type_unique (gnome_canvas_item_get_type (), &e_icon_bar_bg_item_info);
}
return e_icon_bar_bg_item_type;
}
static void
e_icon_bar_bg_item_class_init (EIconBarBgItemClass *class)
{
GtkObjectClass *object_class;
GnomeCanvasItemClass *item_class;
parent_class = gtk_type_class (gnome_canvas_item_get_type());
object_class = (GtkObjectClass *) class;
item_class = (GnomeCanvasItemClass *) class;
gtk_object_add_arg_type ("EIconBarBgItem::icon_bar",
GTK_TYPE_POINTER, GTK_ARG_WRITABLE,
ARG_ICON_BAR);
object_class->set_arg = e_icon_bar_bg_item_set_arg;
/* GnomeCanvasItem method overrides */
item_class->update = e_icon_bar_bg_item_update;
item_class->draw = e_icon_bar_bg_item_draw;
item_class->point = e_icon_bar_bg_item_point;
item_class->event = e_icon_bar_bg_item_event;
}
static void
e_icon_bar_bg_item_init (EIconBarBgItem *ibitem)
{
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (ibitem);
ibitem->icon_bar = NULL;
item->x1 = 0;
item->y1 = 0;
item->x2 = 0;
item->y2 = 0;
}
static void
e_icon_bar_bg_item_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
{
GnomeCanvasItem *item;
EIconBarBgItem *ibitem;
item = GNOME_CANVAS_ITEM (o);
ibitem = E_ICON_BAR_BG_ITEM (o);
switch (arg_id){
case ARG_ICON_BAR:
ibitem->icon_bar = GTK_VALUE_POINTER (*arg);
break;
}
}
static void
e_icon_bar_bg_item_update (GnomeCanvasItem *item,
double *affine,
ArtSVP *clip_path,
int flags)
{
if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update)
(* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags);
/* The grid covers the entire canvas area. */
item->x1 = 0;
item->y1 = 0;
item->x2 = INT_MAX;
item->y2 = INT_MAX;
}
/*
* DRAWING ROUTINES - functions to paint the canvas item.
*/
static void
e_icon_bar_bg_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable,
int x, int y, int width, int height)
{
EIconBar *icon_bar;
EIconBarItem *item;
EIconBarBgItem *ibitem;
GtkStyle *style;
GdkGC *gc;
GtkShadowType shadow;
gint item_num, border, bar_x, bar_y, bar_w, i, arrow_height;
ibitem = E_ICON_BAR_BG_ITEM (canvas_item);
icon_bar = ibitem->icon_bar;
g_return_if_fail (icon_bar != NULL);
style = GTK_WIDGET (icon_bar)->style;
/* Draw the highlight around the current highlight item. */
item_num = -1;
if (icon_bar->editing_item_num == -1) {
if (icon_bar->pressed_item_num != -1) {
item_num = icon_bar->pressed_item_num;
if (icon_bar->pressed_item_num == icon_bar->mouse_over_item_num)
shadow = GTK_SHADOW_IN;
else
shadow = GTK_SHADOW_OUT;
} else if (icon_bar->mouse_over_item_num != -1) {
item_num = icon_bar->mouse_over_item_num;
shadow = GTK_SHADOW_OUT;
}
}
if (item_num != -1) {
item = &g_array_index (icon_bar->items, EIconBarItem,
item_num);
if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS)
border = E_ICON_BAR_LARGE_ICON_SHADOW_BORDER;
else
border = E_ICON_BAR_SMALL_ICON_SHADOW_BORDER;
gtk_draw_shadow (style, drawable, GTK_STATE_NORMAL, shadow,
icon_bar->icon_x - border - x,
item->icon_y - border - y,
icon_bar->icon_w + border * 2 - 1,
icon_bar->icon_h + border * 2 - 1);
}
/* Draw the bar between items when dragging, if needed. */
if (icon_bar->in_drag && icon_bar->dragging_before_item_num != -1) {
if (icon_bar->dragging_before_item_num < icon_bar->items->len) {
item = &g_array_index (icon_bar->items, EIconBarItem,
icon_bar->dragging_before_item_num);
bar_y = 0;
} else {
/* We need to draw the bar after the last item. */
item = &g_array_index (icon_bar->items, EIconBarItem,
icon_bar->items->len - 1);
bar_y = item->item_height + icon_bar->spacing;
}
if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS) {
bar_y += item->icon_y;
} else {
bar_y += MIN (item->icon_y, item->text_y);
}
bar_y -= y + icon_bar->spacing / 2;
bar_x = E_ICON_BAR_BG_ITEM_BAR_OFFSET - x;
bar_w = GTK_WIDGET (icon_bar)->allocation.width - 2 * E_ICON_BAR_BG_ITEM_BAR_OFFSET - 1;
gc = GTK_WIDGET (icon_bar)->style->fg_gc[GTK_STATE_NORMAL];
/* Draw the horizontal bar. */
gdk_draw_rectangle (drawable, gc, TRUE,
bar_x, bar_y,
bar_w, E_ICON_BAR_BG_ITEM_BAR_HEIGHT);
if (icon_bar->view_type == E_ICON_BAR_LARGE_ICONS)
arrow_height = E_ICON_BAR_BG_ITEM_LARGE_ARROW_HEIGHT / 2;
else
arrow_height = E_ICON_BAR_BG_ITEM_SMALL_ARROW_HEIGHT / 2;
/* Draw the arrows at the end of the lines. We use
gdk_draw_line() to draw a series of vertical lines, since
gdk_draw_polygon() produces odd results. */
i = 0;
while (arrow_height > 0) {
gdk_draw_line (drawable, gc,
bar_x + i,
bar_y - arrow_height,
bar_x + i,
bar_y + arrow_height);
gdk_draw_line (drawable, gc,
bar_x + bar_w - i - 1,
bar_y - arrow_height,
bar_x + bar_w - i - 1,
bar_y + arrow_height);
arrow_height--;
i++;
}
}
}
/* This is supposed to return the nearest item the the point and the distance.
Since we are the only item we just return ourself and 0 for the distance.
This is needed so that we get button/motion events. */
static double
e_icon_bar_bg_item_point (GnomeCanvasItem *item, double x, double y,
int cx, int cy,
GnomeCanvasItem **actual_item)
{
*actual_item = item;
return 0.0;
}
static gint
e_icon_bar_bg_item_event (GnomeCanvasItem *item, GdkEvent *event)
{
EIconBarBgItem *ibitem;
ibitem = E_ICON_BAR_BG_ITEM (item);
switch (event->type) {
case GDK_BUTTON_PRESS:
return e_icon_bar_bg_item_button_press (ibitem, event);
case GDK_BUTTON_RELEASE:
return e_icon_bar_bg_item_button_release (ibitem, event);
case GDK_MOTION_NOTIFY:
return e_icon_bar_bg_item_motion_notify (ibitem, event);
default:
break;
}
return FALSE;
}
static gint
e_icon_bar_bg_item_button_press (EIconBarBgItem *ibitem,
GdkEvent *event)
{
gint item_num;
item_num = e_icon_bar_find_item_at_position (ibitem->icon_bar,
event->button.x,
event->button.y,
NULL);
e_icon_bar_item_pressed (ibitem->icon_bar, item_num, event);
return TRUE;
}
static gint
e_icon_bar_bg_item_button_release (EIconBarBgItem *ibitem,
GdkEvent *event)
{
gint item_num;
item_num = e_icon_bar_find_item_at_position (ibitem->icon_bar,
event->button.x,
event->button.y,
NULL);
e_icon_bar_item_released (ibitem->icon_bar, item_num, event);
return TRUE;
}
static gint
e_icon_bar_bg_item_motion_notify (EIconBarBgItem *ibitem,
GdkEvent *event)
{
gint item_num;
item_num = e_icon_bar_find_item_at_position (ibitem->icon_bar,
event->motion.x,
event->motion.y,
NULL);
e_icon_bar_item_motion (ibitem->icon_bar, item_num, event);
return TRUE;
}

View File

@ -0,0 +1,72 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* EIconBarBgItem - A GnomeCanvasItem which covers the entire EIconBar.
* It paints the rectangles around items when the mouse moves over them, and
* the lines between items when dragging.
*/
#ifndef _E_ICON_BAR_BG_ITEM_H_
#define _E_ICON_BAR_BG_ITEM_H_
#include <libgnomeui/gnome-canvas.h>
#include "e-icon-bar.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define E_ICON_BAR_BG_ITEM(obj) (GTK_CHECK_CAST((obj), e_icon_bar_bg_item_get_type (), EIconBarBgItem))
#define E_ICON_BAR_BG_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), e_icon_bar_bg_item_get_type (), EIconBarBgItemClass))
#define E_IS_ICON_BAR_BG_ITEM(o) (GTK_CHECK_TYPE((o), e_icon_bar_bg_item_get_type ()))
typedef struct _EIconBarBgItem EIconBarBgItem;
typedef struct _EIconBarBgItemClass EIconBarBgItemClass;
struct _EIconBarBgItem
{
GnomeCanvasItem canvas_item;
/* The parent EIconBar widget. */
EIconBar *icon_bar;
};
struct _EIconBarBgItemClass
{
GnomeCanvasItemClass parent_class;
};
GtkType e_icon_bar_bg_item_get_type (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_ICON_BAR_BG_ITEM_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* Based on gnome-icon-text-item: an editable text block with word wrapping
* for the GNOME canvas.
*
* Copyright (C) 1998, 1999 The Free Software Foundation
*
* Authors: Miguel de Icaza <miguel@gnu.org>
* Federico Mena <federico@gimp.org>
*/
/*
* EIconBarTextItem - An editable canvas text item for the EIconBar.
*/
#ifndef _E_ICON_BAR_TEXT_ITEM_H_
#define _E_ICON_BAR_TEXT_ITEM_H_
#include <gtk/gtkentry.h>
#include <libgnomeui/gnome-canvas.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define E_ICON_BAR_TEXT_ITEM(obj) (GTK_CHECK_CAST((obj), \
e_icon_bar_text_item_get_type (), EIconBarTextItem))
#define E_ICON_BAR_TEXT_ITEM_CLASS(k) (GTK_CHECK_CLASS_CAST ((k),\
e_icon_bar_text_item_get_type ()))
#define E_IS_ICON_BAR_TEXT_ITEM(o) (GTK_CHECK_TYPE((o), \
e_icon_bar_text_item_get_type ()))
typedef struct _EIconBarTextItemInfo EIconBarTextItemInfo;
typedef struct {
GnomeCanvasItem canvas_item;
/* Size and maximum allowed width */
int x, y;
int width;
/* Font name */
char *fontname;
/* Private data */
gpointer priv; /* was GtkEntry *entry */
/* Actual text */
char *text;
/* Text layout information */
EIconBarTextItemInfo *ti;
/* Whether the text is being edited */
unsigned int editing : 1;
/* Whether the text item is selected */
unsigned int selected : 1;
/* Whether the user is select-dragging a block of text */
unsigned int selecting : 1;
/* Whether the text is editable */
unsigned int is_editable : 1;
/* Whether the text is allocated by us (FALSE if allocated by the client) */
unsigned int is_text_allocated : 1;
/* The horizontal alignment of the text (default 0.5). */
gfloat xalign;
/* The justification of the text (default is centered). */
GtkJustification justification;
/* The max number of lines of text shown, or -1 for all (default). */
gint max_lines;
/* If '...' is displayed if the text doesn't all fit (default TRUE). */
gboolean show_ellipsis;
/* This is TRUE if we couldn't fit all the text in. */
gboolean is_clipped;
} EIconBarTextItem;
typedef struct {
GnomeCanvasItemClass parent_class;
/* Signals we emit */
int (* text_changed) (EIconBarTextItem *iti);
void (* height_changed) (EIconBarTextItem *iti);
void (* width_changed) (EIconBarTextItem *iti);
void (* editing_started) (EIconBarTextItem *iti);
void (* editing_stopped) (EIconBarTextItem *iti);
void (* selection_started) (EIconBarTextItem *iti);
void (* selection_stopped) (EIconBarTextItem *iti);
} EIconBarTextItemClass;
GtkType e_icon_bar_text_item_get_type (void);
void e_icon_bar_text_item_configure (EIconBarTextItem *iti,
int x,
int y,
int width,
const char *fontname,
const char *text,
gboolean is_static);
void e_icon_bar_text_item_set_width (EIconBarTextItem *iti,
int width);
void e_icon_bar_text_item_setxy (EIconBarTextItem *iti,
int x,
int y);
void e_icon_bar_text_item_select (EIconBarTextItem *iti,
int sel);
char* e_icon_bar_text_item_get_text (EIconBarTextItem *iti);
void e_icon_bar_text_item_set_text (EIconBarTextItem *iti,
const char *text,
gboolean is_static);
void e_icon_bar_text_item_start_editing (EIconBarTextItem *iti);
void e_icon_bar_text_item_stop_editing (EIconBarTextItem *iti,
gboolean accept);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_ICON_BAR_TEXT_ITEM_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,221 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#ifndef _E_ICON_BAR_H_
#define _E_ICON_BAR_H_
#include <gdk_imlib.h>
#include <libgnomeui/gnome-canvas.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* EIconBar is a subclass of GnomeCanvas for displaying a vertical column of
* icons and descriptions. It provides 2 views - large icons and small icons.
*/
/* This contains information on one item. */
typedef struct _EIconBarItem EIconBarItem;
struct _EIconBarItem
{
GnomeCanvasItem *text;
GnomeCanvasItem *image;
/* This is user data attached to the item, e.g. a URL. */
gpointer data;
GtkDestroyNotify destroy;
/* This is the height of the item. */
gint item_height;
/* This is the actual x, width and height of the text, rather than
the maximum allowed area. */
gint text_x;
gint text_width;
gint text_height;
gint icon_y, text_y;
};
/* These are the view types. Defaults to LARGE_ICONS. */
typedef enum
{
E_ICON_BAR_LARGE_ICONS,
E_ICON_BAR_SMALL_ICONS
} EIconBarViewType;
#define E_ICON_BAR(obj) GTK_CHECK_CAST (obj, e_icon_bar_get_type (), EIconBar)
#define E_ICON_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_icon_bar_get_type (), EIconBarClass)
#define E_IS_ICON_BAR(obj) GTK_CHECK_TYPE (obj, e_icon_bar_get_type ())
typedef struct _EIconBar EIconBar;
typedef struct _EIconBarClass EIconBarClass;
struct _EIconBar
{
GnomeCanvas canvas;
/* This specifies if we are using large icons or small icons. */
EIconBarViewType view_type;
/* This is an array of EIconBarItem elements. */
GArray *items;
/* This is the index of the item which has been pressed, or -1.
It will be shown as pressed in while the mouse is over it. */
gint pressed_item_num;
/* This is the coordinates of where the button was pressed. If the
mouse moves a certain distance with the button still pressed, we
start a drag. */
gint pressed_x;
gint pressed_y;
/* This is the index of the item the mouse is currently over, or -1.
It will be highlighted unless one of the items is pressed. */
gint mouse_over_item_num;
/* This is the item that we are currently editing, or -1. */
gint editing_item_num;
/* This is the index of the item which is being dragged, or -1.
If the drag results in a move it will be deleted. */
gint dragged_item_num;
/* This is TRUE if we are dragging over this EIconBar. */
gboolean in_drag;
/* This is used in drag-and-drop to indicate the item which the mouse
is currently before, e.g. if it is 1 then a dropped item would be
inserted between items 0 and 1. It ranges from 0 to the number of
items, or is -1 when the mouse is not dragging between items. */
gint dragging_before_item_num;
/* These are the common positions of all the items in the EIconBar. */
gint icon_x, icon_w, icon_h, text_x, text_w, spacing;
/* This is the source id of our auto-scroll timeout handler, used when
in the middle of drag-and-drop operations. */
gint auto_scroll_timeout_id;
gint auto_scroll_delay;
gboolean scrolling_up;
};
struct _EIconBarClass
{
GnomeCanvasClass parent_class;
void (*selected_item) (EIconBar *icon_bar,
GdkEvent *event,
gint item_num);
void (*dragged_item) (EIconBar *icon_bar,
GdkEvent *event,
gint item_num);
};
GtkType e_icon_bar_get_type (void);
GtkWidget* e_icon_bar_new (void);
/* Sets the view type. */
void e_icon_bar_set_view_type (EIconBar *icon_bar,
EIconBarViewType view_type);
/* Adds a new item to a group at the given position. If position is -1 it is
added at the end. It returns the index of the item. */
gint e_icon_bar_add_item (EIconBar *icon_bar,
GdkImlibImage *image,
gchar *text,
gint position);
/* Reorders an item. Note that position refers to the new position to add the
item after removing it from its current position. If position is -1 it is
moved to the end of the bar. */
void e_icon_bar_reorder_item (EIconBar *icon_bar,
gint item_num,
gint new_position);
void e_icon_bar_remove_item (EIconBar *icon_bar,
gint item_num);
GdkImlibImage* e_icon_bar_get_item_image (EIconBar *icon_bar,
gint item_num);
void e_icon_bar_set_item_image (EIconBar *icon_bar,
gint item_num,
GdkImlibImage *image);
gchar* e_icon_bar_get_item_text (EIconBar *icon_bar,
gint item_num);
void e_icon_bar_set_item_text (EIconBar *icon_bar,
gint item_num,
gchar *text);
gpointer e_icon_bar_get_item_data (EIconBar *icon_bar,
gint item_num);
void e_icon_bar_set_item_data (EIconBar *icon_bar,
gint item_num,
gpointer data);
void e_icon_bar_set_item_data_full (EIconBar *icon_bar,
gint item_num,
gpointer data,
GtkDestroyNotify destroy);
void e_icon_bar_start_editing_item (EIconBar *icon_bar,
gint item_num);
void e_icon_bar_stop_editing_item (EIconBar *icon_bar,
gboolean accept);
/*
* INTERNAL FUNCTIONS - for use by EIconBarBgItem.
*/
/* This returns the index of the item at the given position on the EIconBar,
or -1 if no item is found. If before_item is not NULL, it returns the
item which the mouse is before, or -1 (this is used for dragging). */
gint e_icon_bar_find_item_at_position (EIconBar *icon_bar,
gint x,
gint y,
gint *before_item);
void e_icon_bar_item_pressed (EIconBar *icon_bar,
gint item_num,
GdkEvent *event);
void e_icon_bar_item_released (EIconBar *icon_bar,
gint item_num,
GdkEvent *event);
void e_icon_bar_item_motion (EIconBar *icon_bar,
gint item_num,
GdkEvent *event);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_ICON_BAR_H_ */

View File

@ -0,0 +1,563 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* ShortcutBar displays a vertical bar with a number of Groups, each of which
* contains any number of icons. It is used on the left of the main application
* window so users can easily access items such as folders and files.
*/
#include <string.h>
#include <gnome.h>
#include "e-shortcut-bar.h"
#include "e-clipped-label.h"
#include "e-vscrolled-bar.h"
/* Drag and Drop stuff. */
enum {
TARGET_SHORTCUT
};
static GtkTargetEntry target_table[] = {
{ "E-SHORTCUT", 0, TARGET_SHORTCUT }
};
static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
typedef struct _EShortcutBarBuiltinType EShortcutBarBuiltinType;
struct _EShortcutBarBuiltinType {
gchar *name;
gchar *filename;
GdkImlibImage *image;
};
EShortcutBarBuiltinType e_shortcut_bar_builtin_types[] = {
{ "folder:", "gnome-word.png", NULL },
{ "calendar:", "gnome-calendar.png", NULL },
{ "todo:", "gnome-cromagnon.png", NULL },
{ "contacts:", "gnome-ccthemes.png", NULL }
};
static gint e_shortcut_bar_num_builtin_types = sizeof (e_shortcut_bar_builtin_types) / sizeof (EShortcutBarBuiltinType);
gboolean e_shortcut_bar_default_type_image_loaded = FALSE;
GdkImlibImage *e_shortcut_bar_default_type_image = NULL;
gchar *e_shortcut_bar_default_type_filename = "gnome-balsa2.png";
static void e_shortcut_bar_class_init (EShortcutBarClass *class);
static void e_shortcut_bar_init (EShortcutBar *shortcut_bar);
static void e_shortcut_bar_destroy (GtkObject *object);
static void e_shortcut_bar_set_canvas_style (EShortcutBar *shortcut_bar,
GtkWidget *canvas);
static void e_shortcut_bar_item_selected (EIconBar *icon_bar,
GdkEvent *event,
gint item_num,
EShortcutBar *shortcut_bar);
static void e_shortcut_bar_item_dragged (EIconBar *icon_bar,
GdkEvent *event,
gint item_num,
EShortcutBar *shortcut_bar);
static void e_shortcut_bar_on_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
EShortcutBar *shortcut_bar);
static void e_shortcut_bar_on_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time,
EShortcutBar *shortcut_bar);
static void e_shortcut_bar_on_drag_data_delete (GtkWidget *widget,
GdkDragContext *context,
EShortcutBar *shortcut_bar);
static void e_shortcut_bar_stop_editing (GtkWidget *button,
EShortcutBar *shortcut_bar);
static GdkImlibImage* e_shortcut_bar_get_image_from_url (EShortcutBar *shortcut_bar,
gchar *item_url);
static GdkImlibImage* e_shortcut_bar_load_image (gchar *filename);
enum
{
ITEM_SELECTED,
LAST_SIGNAL
};
static guint e_shortcut_bar_signals[LAST_SIGNAL] = {0};
static EGroupBarClass *parent_class;
GtkType
e_shortcut_bar_get_type (void)
{
static GtkType e_shortcut_bar_type = 0;
if (!e_shortcut_bar_type){
GtkTypeInfo e_shortcut_bar_info = {
"EShortcutBar",
sizeof (EShortcutBar),
sizeof (EShortcutBarClass),
(GtkClassInitFunc) e_shortcut_bar_class_init,
(GtkObjectInitFunc) e_shortcut_bar_init,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
parent_class = gtk_type_class (e_group_bar_get_type ());
e_shortcut_bar_type = gtk_type_unique (e_group_bar_get_type (),
&e_shortcut_bar_info);
}
return e_shortcut_bar_type;
}
static void
e_shortcut_bar_class_init (EShortcutBarClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
e_shortcut_bar_signals[ITEM_SELECTED] =
gtk_signal_new ("item_selected",
GTK_RUN_LAST | GTK_RUN_ACTION,
object_class->type,
GTK_SIGNAL_OFFSET (EShortcutBarClass,
selected_item),
gtk_marshal_NONE__POINTER_INT_INT,
GTK_TYPE_NONE, 3, GTK_TYPE_GDK_EVENT,
GTK_TYPE_INT, GTK_TYPE_INT);
gtk_object_class_add_signals (object_class, e_shortcut_bar_signals,
LAST_SIGNAL);
/* Method override */
object_class->destroy = e_shortcut_bar_destroy;
}
static void
e_shortcut_bar_init (EShortcutBar *shortcut_bar)
{
shortcut_bar->groups = g_array_new (FALSE, FALSE,
sizeof (EShortcutBarGroup));
}
GtkWidget *
e_shortcut_bar_new (void)
{
GtkWidget *shortcut_bar;
shortcut_bar = GTK_WIDGET (gtk_type_new (e_shortcut_bar_get_type ()));
return shortcut_bar;
}
static void
e_shortcut_bar_destroy (GtkObject *object)
{
EShortcutBar *shortcut_bar;
shortcut_bar = E_SHORTCUT_BAR (object);
GTK_OBJECT_CLASS (parent_class)->destroy (object);
g_array_free (shortcut_bar->groups, TRUE);
}
gint
e_shortcut_bar_add_group (EShortcutBar *shortcut_bar, gchar *group_name)
{
EShortcutBarGroup *group, tmp_group;
gint group_num;
GtkWidget *button, *label;
g_return_val_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar), -1);
g_return_val_if_fail (group_name != NULL, -1);
group_num = shortcut_bar->groups->len;
g_array_append_val (shortcut_bar->groups, tmp_group);
group = &g_array_index (shortcut_bar->groups,
EShortcutBarGroup, group_num);
group->vscrolled_bar = e_vscrolled_bar_new (NULL);
gtk_widget_show (group->vscrolled_bar);
gtk_signal_connect (GTK_OBJECT (E_VSCROLLED_BAR (group->vscrolled_bar)->up_button), "pressed", GTK_SIGNAL_FUNC (e_shortcut_bar_stop_editing), shortcut_bar);
gtk_signal_connect (GTK_OBJECT (E_VSCROLLED_BAR (group->vscrolled_bar)->down_button), "pressed", GTK_SIGNAL_FUNC (e_shortcut_bar_stop_editing), shortcut_bar);
group->icon_bar = e_icon_bar_new ();
gtk_widget_show (group->icon_bar);
gtk_container_add (GTK_CONTAINER (group->vscrolled_bar),
group->icon_bar);
gtk_signal_connect (GTK_OBJECT (group->icon_bar), "item_selected",
GTK_SIGNAL_FUNC (e_shortcut_bar_item_selected),
shortcut_bar);
gtk_signal_connect (GTK_OBJECT (group->icon_bar), "item_dragged",
GTK_SIGNAL_FUNC (e_shortcut_bar_item_dragged),
shortcut_bar);
gtk_signal_connect (GTK_OBJECT (group->icon_bar), "drag_data_get",
GTK_SIGNAL_FUNC (e_shortcut_bar_on_drag_data_get),
shortcut_bar);
gtk_signal_connect (GTK_OBJECT (group->icon_bar), "drag_data_received",
GTK_SIGNAL_FUNC (e_shortcut_bar_on_drag_data_received),
shortcut_bar);
gtk_signal_connect (GTK_OBJECT (group->icon_bar), "drag_data_delete",
GTK_SIGNAL_FUNC (e_shortcut_bar_on_drag_data_delete),
shortcut_bar);
e_shortcut_bar_set_canvas_style (shortcut_bar, group->icon_bar);
button = gtk_button_new ();
label = e_clipped_label_new (group_name);
gtk_misc_set_alignment (GTK_MISC (label), 0.5, 0.5);
gtk_widget_show (label);
gtk_container_add (GTK_CONTAINER (button), label);
gtk_widget_show (button);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (e_shortcut_bar_stop_editing),
shortcut_bar);
gtk_drag_dest_set (GTK_WIDGET (group->icon_bar),
GTK_DEST_DEFAULT_ALL,
target_table, n_targets,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
gtk_drag_dest_set (GTK_WIDGET (button),
GTK_DEST_DEFAULT_ALL,
target_table, n_targets,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
e_group_bar_add_group (E_GROUP_BAR (shortcut_bar),
group->vscrolled_bar, button, -1);
return group_num;
}
void
e_shortcut_bar_remove_group (EShortcutBar *shortcut_bar,
gint group_num)
{
e_group_bar_remove_group (E_GROUP_BAR (shortcut_bar), group_num);
g_array_remove_index (shortcut_bar->groups, group_num);
}
gint
e_shortcut_bar_add_item (EShortcutBar *shortcut_bar, gint group_num,
gchar *item_url, gchar *item_name)
{
EShortcutBarGroup *group;
GdkImlibImage *image;
gint item_num;
g_return_val_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar), -1);
g_return_val_if_fail (group_num >= 0, -1);
g_return_val_if_fail (group_num < shortcut_bar->groups->len, -1);
g_return_val_if_fail (item_url != NULL, -1);
g_return_val_if_fail (item_name != NULL, -1);
image = e_shortcut_bar_get_image_from_url (shortcut_bar, item_url);
group = &g_array_index (shortcut_bar->groups,
EShortcutBarGroup, group_num);
item_num = e_icon_bar_add_item (E_ICON_BAR (group->icon_bar),
image, item_name, -1);
e_icon_bar_set_item_data_full (E_ICON_BAR (group->icon_bar), item_num,
g_strdup (item_url), g_free);
return item_num;
}
void
e_shortcut_bar_remove_item (EShortcutBar *shortcut_bar,
gint group_num,
gint item_num)
{
EShortcutBarGroup *group;
g_return_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar));
g_return_if_fail (group_num >= 0);
g_return_if_fail (group_num < shortcut_bar->groups->len);
group = &g_array_index (shortcut_bar->groups,
EShortcutBarGroup, group_num);
e_icon_bar_remove_item (E_ICON_BAR (group->icon_bar), item_num);
}
static void
e_shortcut_bar_set_canvas_style (EShortcutBar *shortcut_bar,
GtkWidget *canvas)
{
GtkRcStyle *rc_style;
rc_style = gtk_rc_style_new ();
rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_FG | GTK_RC_BG;
rc_style->fg[GTK_STATE_NORMAL].red = 65535;
rc_style->fg[GTK_STATE_NORMAL].green = 65535;
rc_style->fg[GTK_STATE_NORMAL].blue = 65535;
rc_style->bg[GTK_STATE_NORMAL].red = 32512;
rc_style->bg[GTK_STATE_NORMAL].green = 32512;
rc_style->bg[GTK_STATE_NORMAL].blue = 32512;
gtk_widget_modify_style (GTK_WIDGET (canvas), rc_style);
gtk_rc_style_unref (rc_style);
}
void
e_shortcut_bar_set_view_type (EShortcutBar *shortcut_bar,
gint group_num,
EIconBarViewType view_type)
{
EShortcutBarGroup *group;
g_return_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar));
g_return_if_fail (group_num >= 0);
g_return_if_fail (group_num < shortcut_bar->groups->len);
group = &g_array_index (shortcut_bar->groups,
EShortcutBarGroup, group_num);
e_icon_bar_set_view_type (E_ICON_BAR (group->icon_bar), view_type);
}
static void
e_shortcut_bar_item_selected (EIconBar *icon_bar,
GdkEvent *event,
gint item_num,
EShortcutBar *shortcut_bar)
{
gint group_num;
group_num = e_group_bar_get_group_num (E_GROUP_BAR (shortcut_bar),
GTK_WIDGET (icon_bar)->parent);
gtk_signal_emit (GTK_OBJECT (shortcut_bar),
e_shortcut_bar_signals[ITEM_SELECTED],
event, group_num, item_num);
}
static void
e_shortcut_bar_item_dragged (EIconBar *icon_bar,
GdkEvent *event,
gint item_num,
EShortcutBar *shortcut_bar)
{
GtkTargetList *target_list;
gint group_num;
group_num = e_group_bar_get_group_num (E_GROUP_BAR (shortcut_bar),
GTK_WIDGET (icon_bar)->parent);
/* FIXME: free somewhere - drag_end? */
shortcut_bar->dragged_url = g_strdup (e_icon_bar_get_item_data (icon_bar, item_num));
shortcut_bar->dragged_name = g_strdup (e_icon_bar_get_item_text (icon_bar, item_num));
target_list = gtk_target_list_new (target_table, n_targets);
gtk_drag_begin (GTK_WIDGET (icon_bar), target_list,
GDK_ACTION_COPY | GDK_ACTION_MOVE,
1, event);
gtk_target_list_unref (target_list);
}
static void
e_shortcut_bar_on_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
EShortcutBar *shortcut_bar)
{
gchar *data;
if (info == TARGET_SHORTCUT) {
data = g_strdup_printf ("%s%c%s", shortcut_bar->dragged_name,
'\0', shortcut_bar->dragged_url);
gtk_selection_data_set (selection_data, selection_data->target,
8, data,
strlen (shortcut_bar->dragged_name)
+ strlen (shortcut_bar->dragged_url)
+ 2);
g_free (data);
}
}
static void
e_shortcut_bar_on_drag_data_received (GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *data,
guint info,
guint time,
EShortcutBar *shortcut_bar)
{
EShortcutBarGroup *group;
gchar *item_name, *item_url;
EIconBar *icon_bar;
GdkImlibImage *image;
gint group_num, item_num;
icon_bar = E_ICON_BAR (widget);
if ((data->length >= 0) && (data->format == 8)
&& icon_bar->dragging_before_item_num != -1) {
item_name = data->data;
item_url = item_name + strlen (item_name) + 1;
image = e_shortcut_bar_get_image_from_url (shortcut_bar,
item_url);
group_num = e_group_bar_get_group_num (E_GROUP_BAR (shortcut_bar),
GTK_WIDGET (icon_bar)->parent);
group = &g_array_index (shortcut_bar->groups,
EShortcutBarGroup, group_num);
item_num = e_icon_bar_add_item (E_ICON_BAR (group->icon_bar), image, item_name, icon_bar->dragging_before_item_num);
e_icon_bar_set_item_data_full (E_ICON_BAR (group->icon_bar),
item_num, g_strdup (item_url),
g_free);
gtk_drag_finish (context, TRUE, TRUE, time);
return;
}
gtk_drag_finish (context, FALSE, FALSE, time);
}
static void
e_shortcut_bar_on_drag_data_delete (GtkWidget *widget,
GdkDragContext *context,
EShortcutBar *shortcut_bar)
{
EIconBar *icon_bar;
icon_bar = E_ICON_BAR (widget);
e_icon_bar_remove_item (icon_bar, icon_bar->dragged_item_num);
}
void
e_shortcut_bar_start_editing_item (EShortcutBar *shortcut_bar,
gint group_num,
gint item_num)
{
EShortcutBarGroup *group;
g_return_if_fail (E_IS_SHORTCUT_BAR (shortcut_bar));
g_return_if_fail (group_num >= 0);
g_return_if_fail (group_num < shortcut_bar->groups->len);
group = &g_array_index (shortcut_bar->groups,
EShortcutBarGroup, group_num);
e_icon_bar_start_editing_item (E_ICON_BAR (group->icon_bar), item_num);
}
/* We stop editing any item when a scroll button is pressed. */
static void
e_shortcut_bar_stop_editing (GtkWidget *button,
EShortcutBar *shortcut_bar)
{
EShortcutBarGroup *group;
gint group_num;
for (group_num = 0;
group_num < shortcut_bar->groups->len;
group_num++) {
group = &g_array_index (shortcut_bar->groups,
EShortcutBarGroup, group_num);
e_icon_bar_stop_editing_item (E_ICON_BAR (group->icon_bar),
TRUE);
}
}
static GdkImlibImage*
e_shortcut_bar_get_image_from_url (EShortcutBar *shortcut_bar,
gchar *item_url)
{
gchar *method_terminator;
gint method_len, i;
method_terminator = strchr (item_url, ':');
if (method_terminator) {
method_len = method_terminator - item_url + 1;
/* Check if it is a builtin type. */
for (i = 0; i < e_shortcut_bar_num_builtin_types; i++) {
if (!strncmp (item_url, e_shortcut_bar_builtin_types[i].name, method_len)) {
if (!e_shortcut_bar_builtin_types[i].image)
e_shortcut_bar_builtin_types[i].image = e_shortcut_bar_load_image (e_shortcut_bar_builtin_types[i].filename);
return e_shortcut_bar_builtin_types[i].image;
}
}
}
if (!e_shortcut_bar_default_type_image_loaded) {
e_shortcut_bar_default_type_image_loaded = TRUE;
e_shortcut_bar_default_type_image = e_shortcut_bar_load_image (e_shortcut_bar_default_type_filename);
}
return e_shortcut_bar_default_type_image;
}
static GdkImlibImage*
e_shortcut_bar_load_image (gchar *filename)
{
gchar *pathname;
GdkImlibImage *image = NULL;
pathname = gnome_pixmap_file (filename);
if (pathname)
image = gdk_imlib_load_image (pathname);
else
g_warning ("Couldn't find pixmap: %s", filename);
return image;
}

View File

@ -0,0 +1,114 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#ifndef _E_SHORTCUT_BAR_H_
#define _E_SHORTCUT_BAR_H_
#include "e-group-bar.h"
#include "e-icon-bar.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* EShortcutBar displays a vertical bar with a number of Groups, each of which
* contains any number of icons. It is used on the left of the main application
* window so users can easily access items such as folders and files.
*/
/* This contains information on one group. */
typedef struct _EShortcutBarGroup EShortcutBarGroup;
struct _EShortcutBarGroup
{
/* This is the EVScrolledBar which scrolls the group. */
GtkWidget *vscrolled_bar;
/* This is the icon bar containing the child items. */
GtkWidget *icon_bar;
};
#define E_SHORTCUT_BAR(obj) GTK_CHECK_CAST (obj, e_shortcut_bar_get_type (), EShortcutBar)
#define E_SHORTCUT_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_shortcut_bar_get_type (), EShortcutBarClass)
#define E_IS_SHORTCUT_BAR(obj) GTK_CHECK_TYPE (obj, e_shortcut_bar_get_type ())
typedef struct _EShortcutBar EShortcutBar;
typedef struct _EShortcutBarClass EShortcutBarClass;
struct _EShortcutBar
{
EGroupBar group_bar;
/* This is an array of EShortcutBarGroup elements. */
GArray *groups;
gchar *dragged_url;
gchar *dragged_name;
};
struct _EShortcutBarClass
{
EGroupBarClass parent_class;
void (*selected_item) (EShortcutBar *shortcut_bar,
GdkEvent *event,
gint group_num,
gint item_num);
};
GtkType e_shortcut_bar_get_type (void);
GtkWidget* e_shortcut_bar_new (void);
/* Adds a new group, returning the index. */
gint e_shortcut_bar_add_group (EShortcutBar *shortcut_bar,
gchar *group_name);
void e_shortcut_bar_remove_group (EShortcutBar *shortcut_bar,
gint group_num);
/* Sets the view type for the group. */
void e_shortcut_bar_set_view_type (EShortcutBar *shortcut_bar,
gint group_num,
EIconBarViewType view_type);
/* Adds a new item to a group, returning the index within the group. */
gint e_shortcut_bar_add_item (EShortcutBar *shortcut_bar,
gint group_num,
gchar *item_url,
gchar *item_name);
void e_shortcut_bar_start_editing_item (EShortcutBar *shortcut_bar,
gint group_num,
gint item_num);
void e_shortcut_bar_remove_item (EShortcutBar *shortcut_bar,
gint group_num,
gint item_num);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_SHORTCUT_BAR_H_ */

View File

@ -0,0 +1,652 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* EVScrolledBar is like GtkScrolledWindow but only scrolls the child widget
* vertically. It is intended for scrolling narrow vertical bars.
*/
#include <gtk/gtkarrow.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtksignal.h>
#include "e-vscrolled-bar.h"
/* These are the offsets of the up & down buttons from the right and top/bottom
of the widget. */
#define E_VSCROLLED_BAR_BUTTON_X_OFFSET 2
#define E_VSCROLLED_BAR_BUTTON_Y_OFFSET 2
/* This is the time between scrolls. */
#define E_VSCROLLED_BAR_SCROLL_TIMEOUT 20
static void e_vscrolled_bar_class_init (EVScrolledBarClass *class);
static void e_vscrolled_bar_init (EVScrolledBar *vscrolled_bar);
static void e_vscrolled_bar_destroy (GtkObject *object);
static void e_vscrolled_bar_finalize (GtkObject *object);
static void e_vscrolled_bar_map (GtkWidget *widget);
static void e_vscrolled_bar_unmap (GtkWidget *widget);
static void e_vscrolled_bar_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void e_vscrolled_bar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void e_vscrolled_bar_draw (GtkWidget *widget,
GdkRectangle *area);
static void e_vscrolled_bar_add (GtkContainer *container,
GtkWidget *child);
static void e_vscrolled_bar_remove (GtkContainer *container,
GtkWidget *child);
static void e_vscrolled_bar_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data);
static void e_vscrolled_bar_adjustment_changed (GtkAdjustment *adjustment,
gpointer data);
static void e_vscrolled_bar_button_pressed (GtkWidget *button,
EVScrolledBar *vscrolled_bar);
static void e_vscrolled_bar_button_released (GtkWidget *button,
EVScrolledBar *vscrolled_bar);
static void e_vscrolled_bar_button_clicked (GtkWidget *button,
EVScrolledBar *vscrolled_bar);
static gboolean e_vscrolled_bar_timeout_handler (gpointer data);
static GtkBinClass *parent_class;
GtkType
e_vscrolled_bar_get_type (void)
{
static GtkType e_vscrolled_bar_type = 0;
if (!e_vscrolled_bar_type) {
GtkTypeInfo e_vscrolled_bar_info = {
"EVScrolledBar",
sizeof (EVScrolledBar),
sizeof (EVScrolledBarClass),
(GtkClassInitFunc) e_vscrolled_bar_class_init,
(GtkObjectInitFunc) e_vscrolled_bar_init,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
parent_class = gtk_type_class (GTK_TYPE_BIN);
e_vscrolled_bar_type = gtk_type_unique (GTK_TYPE_BIN,
&e_vscrolled_bar_info);
}
return e_vscrolled_bar_type;
}
static void
e_vscrolled_bar_class_init (EVScrolledBarClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkContainerClass *container_class;
object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
container_class = (GtkContainerClass *) class;
/* Method override */
object_class->destroy = e_vscrolled_bar_destroy;
object_class->finalize = e_vscrolled_bar_finalize;
widget_class->map = e_vscrolled_bar_map;
widget_class->unmap = e_vscrolled_bar_unmap;
widget_class->size_request = e_vscrolled_bar_size_request;
widget_class->size_allocate = e_vscrolled_bar_size_allocate;
widget_class->draw = e_vscrolled_bar_draw;
container_class->add = e_vscrolled_bar_add;
container_class->remove = e_vscrolled_bar_remove;
container_class->forall = e_vscrolled_bar_forall;
}
static void
e_vscrolled_bar_init (EVScrolledBar *vscrolled_bar)
{
GtkWidget *arrow;
GTK_WIDGET_SET_FLAGS (vscrolled_bar, GTK_NO_WINDOW);
gtk_container_set_resize_mode (GTK_CONTAINER (vscrolled_bar),
GTK_RESIZE_QUEUE);
gtk_widget_push_composite_child ();
vscrolled_bar->up_button = gtk_button_new ();
gtk_widget_set_composite_name (vscrolled_bar->up_button,
"up_button");
gtk_widget_set_parent (vscrolled_bar->up_button,
GTK_WIDGET (vscrolled_bar));
arrow = gtk_arrow_new (GTK_ARROW_UP, GTK_SHADOW_OUT);
gtk_misc_set_padding (GTK_MISC (arrow), 1, 1);
gtk_widget_show (arrow);
gtk_container_add (GTK_CONTAINER (vscrolled_bar->up_button), arrow);
gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->up_button), "pressed", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_pressed), vscrolled_bar);
gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->up_button), "released", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_released), vscrolled_bar);
gtk_signal_connect (GTK_OBJECT (vscrolled_bar->up_button), "clicked", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_clicked), vscrolled_bar);
vscrolled_bar->down_button = gtk_button_new ();
gtk_widget_set_composite_name (vscrolled_bar->up_button,
"down_button");
gtk_widget_set_parent (vscrolled_bar->down_button,
GTK_WIDGET (vscrolled_bar));
arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
gtk_misc_set_padding (GTK_MISC (arrow), 1, 1);
gtk_widget_show (arrow);
gtk_container_add (GTK_CONTAINER (vscrolled_bar->down_button), arrow);
gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->down_button), "pressed", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_pressed), vscrolled_bar);
gtk_signal_connect_after (GTK_OBJECT (vscrolled_bar->down_button), "released", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_released), vscrolled_bar);
gtk_signal_connect (GTK_OBJECT (vscrolled_bar->down_button), "clicked", GTK_SIGNAL_FUNC (e_vscrolled_bar_button_clicked), vscrolled_bar);
gtk_widget_pop_composite_child ();
vscrolled_bar->adjustment = NULL;
vscrolled_bar->timeout_id = 0;
vscrolled_bar->scrolling_up = FALSE;
vscrolled_bar->min_distance = -1.0;
vscrolled_bar->button_pressed = FALSE;
}
/**
* e_vscrolled_bar_new:
*
* @adjustment: The #GtkAdjustment to use for scrolling, or NULL.
* @Return: A new #EVScrolledBar.
*
* Creates a new #EVScrolledBar with the given adjustment.
**/
GtkWidget *
e_vscrolled_bar_new (GtkAdjustment *adjustment)
{
GtkWidget *vscrolled_bar;
vscrolled_bar = GTK_WIDGET (gtk_type_new (e_vscrolled_bar_get_type ()));
e_vscrolled_bar_set_adjustment (E_VSCROLLED_BAR (vscrolled_bar),
adjustment);
return vscrolled_bar;
}
static void
e_vscrolled_bar_destroy (GtkObject *object)
{
EVScrolledBar *vscrolled_bar;
vscrolled_bar = E_VSCROLLED_BAR (object);
if (vscrolled_bar->timeout_id) {
g_source_remove (vscrolled_bar->timeout_id);
vscrolled_bar->timeout_id = 0;
}
gtk_widget_unparent (vscrolled_bar->up_button);
gtk_widget_unparent (vscrolled_bar->down_button);
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
e_vscrolled_bar_finalize (GtkObject *object)
{
EVScrolledBar *vscrolled_bar;
vscrolled_bar = E_VSCROLLED_BAR (object);
gtk_object_unref (GTK_OBJECT (vscrolled_bar->adjustment));
GTK_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
e_vscrolled_bar_map (GtkWidget *widget)
{
EVScrolledBar *vscrolled_bar;
g_return_if_fail (widget != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (widget));
vscrolled_bar = E_VSCROLLED_BAR (widget);
/* chain parent class handler to map self and child */
GTK_WIDGET_CLASS (parent_class)->map (widget);
if (GTK_WIDGET_VISIBLE (vscrolled_bar->up_button) &&
!GTK_WIDGET_MAPPED (vscrolled_bar->up_button))
gtk_widget_map (vscrolled_bar->up_button);
if (GTK_WIDGET_VISIBLE (vscrolled_bar->down_button) &&
!GTK_WIDGET_MAPPED (vscrolled_bar->down_button))
gtk_widget_map (vscrolled_bar->down_button);
}
static void
e_vscrolled_bar_unmap (GtkWidget *widget)
{
EVScrolledBar *vscrolled_bar;
g_return_if_fail (widget != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (widget));
vscrolled_bar = E_VSCROLLED_BAR (widget);
/* chain parent class handler to unmap self and child */
GTK_WIDGET_CLASS (parent_class)->unmap (widget);
if (GTK_WIDGET_MAPPED (vscrolled_bar->up_button))
gtk_widget_unmap (vscrolled_bar->up_button);
if (GTK_WIDGET_MAPPED (vscrolled_bar->down_button))
gtk_widget_unmap (vscrolled_bar->down_button);
}
static void
e_vscrolled_bar_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
EVScrolledBar *vscrolled_bar;
GtkBin *bin;
GtkRequisition child_requisition;
g_return_if_fail (widget != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (widget));
g_return_if_fail (requisition != NULL);
vscrolled_bar = E_VSCROLLED_BAR (widget);
bin = GTK_BIN (widget);
requisition->width = 0;
requisition->height = 0;
/* We just return the requisition of the child widget, plus the
border width. */
if (bin->child && GTK_WIDGET_VISIBLE (bin->child)) {
gtk_widget_size_request (bin->child, &child_requisition);
*requisition = child_requisition;
}
/* We remember the requested heights of the up & down buttons. */
gtk_widget_size_request (vscrolled_bar->up_button,
&child_requisition);
vscrolled_bar->up_button_width = child_requisition.width;
vscrolled_bar->up_button_height = child_requisition.height;
gtk_widget_size_request (vscrolled_bar->down_button,
&child_requisition);
vscrolled_bar->down_button_width = child_requisition.width;
vscrolled_bar->down_button_height = child_requisition.height;
/* Add on the standard container border widths. */
requisition->width += GTK_CONTAINER (widget)->border_width * 2;
requisition->height += GTK_CONTAINER (widget)->border_width * 2;
}
static void
e_vscrolled_bar_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
EVScrolledBar *vscrolled_bar;
GtkBin *bin;
GtkAllocation button_allocation, child_allocation;
gint border_width;
g_return_if_fail (widget != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (widget));
g_return_if_fail (allocation != NULL);
vscrolled_bar = E_VSCROLLED_BAR (widget);
bin = GTK_BIN (widget);
widget->allocation = *allocation;
border_width = GTK_CONTAINER (widget)->border_width;
child_allocation.x = border_width;
child_allocation.y = border_width;
child_allocation.width = allocation->width - 2 * border_width;
child_allocation.height = allocation->height - 2 * border_width;
gtk_widget_size_allocate (bin->child, &child_allocation);
button_allocation.x = allocation->width - border_width
- vscrolled_bar->up_button_width
- E_VSCROLLED_BAR_BUTTON_X_OFFSET;
button_allocation.y = border_width + E_VSCROLLED_BAR_BUTTON_Y_OFFSET;
button_allocation.width = vscrolled_bar->up_button_width;
button_allocation.height = vscrolled_bar->up_button_height;
gtk_widget_size_allocate (vscrolled_bar->up_button,
&button_allocation);
button_allocation.x = allocation->width - border_width
- vscrolled_bar->down_button_width
- E_VSCROLLED_BAR_BUTTON_X_OFFSET;
button_allocation.y = allocation->height - border_width
- vscrolled_bar->down_button_height
- E_VSCROLLED_BAR_BUTTON_Y_OFFSET;
button_allocation.width = vscrolled_bar->down_button_width;
button_allocation.height = vscrolled_bar->down_button_height;
gtk_widget_size_allocate (vscrolled_bar->down_button,
&button_allocation);
}
static void
e_vscrolled_bar_draw (GtkWidget *widget,
GdkRectangle *area)
{
EVScrolledBar *vscrolled_bar;
GtkBin *bin;
GdkRectangle child_area;
g_return_if_fail (widget != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (widget));
g_return_if_fail (area != NULL);
vscrolled_bar = E_VSCROLLED_BAR (widget);
bin = GTK_BIN (widget);
if (bin->child && GTK_WIDGET_VISIBLE (bin->child) &&
gtk_widget_intersect (bin->child, area, &child_area))
gtk_widget_draw (bin->child, &child_area);
if (GTK_WIDGET_VISIBLE (vscrolled_bar->up_button) &&
gtk_widget_intersect (vscrolled_bar->up_button, area, &child_area))
gtk_widget_draw (vscrolled_bar->up_button, &child_area);
if (GTK_WIDGET_VISIBLE (vscrolled_bar->down_button) &&
gtk_widget_intersect (vscrolled_bar->down_button, area, &child_area))
gtk_widget_draw (vscrolled_bar->down_button, &child_area);
}
static void
e_vscrolled_bar_add (GtkContainer *container,
GtkWidget *child)
{
EVScrolledBar *vscrolled_bar;
GtkBin *bin;
g_return_if_fail (container != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (container));
vscrolled_bar = E_VSCROLLED_BAR (container);
bin = GTK_BIN (container);
g_return_if_fail (bin->child == NULL);
bin->child = child;
gtk_widget_set_parent (child, GTK_WIDGET (bin));
gtk_widget_set_scroll_adjustments (child, NULL,
vscrolled_bar->adjustment);
if (GTK_WIDGET_REALIZED (child->parent))
gtk_widget_realize (child);
if (GTK_WIDGET_VISIBLE (child->parent) && GTK_WIDGET_VISIBLE (child)) {
if (GTK_WIDGET_MAPPED (child->parent))
gtk_widget_map (child);
gtk_widget_queue_resize (child);
}
}
static void
e_vscrolled_bar_remove (GtkContainer *container,
GtkWidget *child)
{
g_return_if_fail (container != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (container));
g_return_if_fail (child != NULL);
g_return_if_fail (GTK_BIN (container)->child == child);
gtk_widget_set_scroll_adjustments (child, NULL, NULL);
/* chain parent class handler to remove child */
GTK_CONTAINER_CLASS (parent_class)->remove (container, child);
}
static void
e_vscrolled_bar_forall (GtkContainer *container,
gboolean include_internals,
GtkCallback callback,
gpointer callback_data)
{
g_return_if_fail (container != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (container));
g_return_if_fail (callback != NULL);
GTK_CONTAINER_CLASS (parent_class)->forall (container,
include_internals,
callback,
callback_data);
if (include_internals) {
EVScrolledBar *vscrolled_bar;
vscrolled_bar = E_VSCROLLED_BAR (container);
if (vscrolled_bar->up_button)
callback (vscrolled_bar->up_button, callback_data);
if (vscrolled_bar->down_button)
callback (vscrolled_bar->down_button, callback_data);
}
}
/**
* e_vscrolled_bar_get_adjustment:
*
* @vscrolled_bar: An #EVScrolledBar.
* @Return: The #GtkAdjustment used for scrolling @vscrolled_bar.
*
* Returns the #GtkAdjustment used for scrolling the #EVscrolledBar.
**/
GtkAdjustment*
e_vscrolled_bar_get_adjustment (EVScrolledBar *vscrolled_bar)
{
g_return_val_if_fail (vscrolled_bar != NULL, NULL);
g_return_val_if_fail (E_IS_VSCROLLED_BAR (vscrolled_bar), NULL);
return vscrolled_bar->adjustment;
}
/**
* e_vscrolled_bar_set_adjustment:
*
* @vscrolled_bar: An #EVScrolledBar.
* @adjustment: The #GtkAdjustment to use for scrolling @vscrolled_bar.
*
* Sets the #GtkAdjustment to use for scrolling the #EVscrolledBar.
**/
void
e_vscrolled_bar_set_adjustment (EVScrolledBar *vscrolled_bar,
GtkAdjustment *adjustment)
{
g_return_if_fail (vscrolled_bar != NULL);
g_return_if_fail (E_IS_VSCROLLED_BAR (vscrolled_bar));
if (adjustment)
g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
else
adjustment = (GtkAdjustment*) gtk_object_new (GTK_TYPE_ADJUSTMENT, NULL);
if (vscrolled_bar->adjustment == adjustment)
return;
if (vscrolled_bar->adjustment) {
gtk_signal_disconnect_by_func (GTK_OBJECT (vscrolled_bar->adjustment),
GTK_SIGNAL_FUNC (e_vscrolled_bar_adjustment_changed),
vscrolled_bar);
gtk_object_unref (GTK_OBJECT (vscrolled_bar->adjustment));
}
vscrolled_bar->adjustment = adjustment;
gtk_object_ref (GTK_OBJECT (vscrolled_bar->adjustment));
gtk_object_sink (GTK_OBJECT (vscrolled_bar->adjustment));
/* I've used connect_after here to avoid a problem when using a
GnomeCanvas as the child widget. When just using connect it would
leave a blank space when one of the buttons is hidden. We want
the GtkLayout to handle the scrolling before we hide any buttons. */
gtk_signal_connect_after (GTK_OBJECT (adjustment), "changed",
GTK_SIGNAL_FUNC (e_vscrolled_bar_adjustment_changed),
vscrolled_bar);
gtk_signal_connect_after (GTK_OBJECT (adjustment), "value_changed",
GTK_SIGNAL_FUNC (e_vscrolled_bar_adjustment_changed),
vscrolled_bar);
e_vscrolled_bar_adjustment_changed (adjustment, vscrolled_bar);
if (GTK_BIN (vscrolled_bar)->child)
gtk_widget_set_scroll_adjustments (GTK_BIN (vscrolled_bar)->child, NULL, adjustment);
}
static void
e_vscrolled_bar_adjustment_changed (GtkAdjustment *adjustment,
gpointer data)
{
EVScrolledBar *vscrolled_bar;
g_return_if_fail (adjustment != NULL);
g_return_if_fail (data != NULL);
vscrolled_bar = E_VSCROLLED_BAR (data);
/* If the adjustment value is not 0, show the up button. */
if (adjustment->value != 0)
gtk_widget_show (vscrolled_bar->up_button);
else
gtk_widget_hide (vscrolled_bar->up_button);
/* If the adjustment value is less than the maximum value, show the
down button. */
if (adjustment->value < adjustment->upper - adjustment->page_size)
gtk_widget_show (vscrolled_bar->down_button);
else
gtk_widget_hide (vscrolled_bar->down_button);
}
static void
e_vscrolled_bar_button_pressed (GtkWidget *button,
EVScrolledBar *vscrolled_bar)
{
if (vscrolled_bar->timeout_id != 0)
g_source_remove (vscrolled_bar->timeout_id);
vscrolled_bar->timeout_id = g_timeout_add (E_VSCROLLED_BAR_SCROLL_TIMEOUT, e_vscrolled_bar_timeout_handler, vscrolled_bar);
vscrolled_bar->scrolling_up = (button == vscrolled_bar->up_button) ? TRUE : FALSE;
vscrolled_bar->min_distance = vscrolled_bar->adjustment->page_size / 4;
vscrolled_bar->button_pressed = TRUE;
e_vscrolled_bar_timeout_handler (vscrolled_bar);
}
static void
e_vscrolled_bar_button_released (GtkWidget *button,
EVScrolledBar *vscrolled_bar)
{
vscrolled_bar->button_pressed = FALSE;
}
/* This will be called when the user hits the space key to activate the button.
It will also be called just before button_released() is called, but since
we already handle that we simply return if the button is pressed. */
static void
e_vscrolled_bar_button_clicked (GtkWidget *button,
EVScrolledBar *vscrolled_bar)
{
if (vscrolled_bar->button_pressed)
return;
/* We act as if the button is pressed and released immediately. */
e_vscrolled_bar_button_pressed (button, vscrolled_bar);
vscrolled_bar->button_pressed = FALSE;
}
static gboolean
e_vscrolled_bar_timeout_handler (gpointer data)
{
EVScrolledBar *vscrolled_bar;
GtkAdjustment *adjustment;
gfloat new_value;
gboolean retval = TRUE;
vscrolled_bar = E_VSCROLLED_BAR (data);
adjustment = vscrolled_bar->adjustment;
GDK_THREADS_ENTER ();
/* Check if the user has released the button and we have already
scrolled the minimum distance. */
if (vscrolled_bar->button_pressed == FALSE
&& vscrolled_bar->min_distance <= 0) {
GDK_THREADS_LEAVE ();
return FALSE;
}
vscrolled_bar->min_distance -= adjustment->step_increment;
if (vscrolled_bar->scrolling_up) {
new_value = adjustment->value - adjustment->step_increment;
if (new_value <= adjustment->lower) {
new_value = adjustment->lower;
retval = FALSE;
}
} else {
new_value = adjustment->value + adjustment->step_increment;
if (new_value >= adjustment->upper - adjustment->page_size) {
new_value = adjustment->upper - adjustment->page_size;
retval = FALSE;
}
}
if (adjustment->value != new_value) {
adjustment->value = new_value;
gtk_signal_emit_by_name (GTK_OBJECT (adjustment),
"value_changed");
}
GDK_THREADS_LEAVE ();
return retval;
}

View File

@ -0,0 +1,97 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
#ifndef _E_VSCROLLED_BAR_H_
#define _E_VSCROLLED_BAR_H_
#include <gtk/gtkbin.h>
#include <gtk/gtkadjustment.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* EVScrolledBar is like GtkScrolledWindow but only scrolls the child widget
* vertically. It is intended for scrolling narrow vertical bars.
*/
#define E_VSCROLLED_BAR(obj) GTK_CHECK_CAST (obj, e_vscrolled_bar_get_type (), EVScrolledBar)
#define E_VSCROLLED_BAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, e_vscrolled_bar_get_type (), EVScrolledBarClass)
#define E_IS_VSCROLLED_BAR(obj) GTK_CHECK_TYPE (obj, e_vscrolled_bar_get_type ())
typedef struct _EVScrolledBar EVScrolledBar;
typedef struct _EVScrolledBarClass EVScrolledBarClass;
struct _EVScrolledBar
{
GtkBin bin;
GtkWidget *up_button;
GtkWidget *down_button;
GtkAdjustment *adjustment;
gint up_button_width;
gint up_button_height;
gint down_button_width;
gint down_button_height;
/* The GTK+ event source ID of our timeout handler. */
gint timeout_id;
/* TRUE if we are scrolling up, FALSE if scrolling down. */
gboolean scrolling_up;
/* The minimum distance left to scroll. If the user just clicks a
button we scroll a minimum amount. This is reduced after each
scroll. */
gfloat min_distance;
/* TRUE if the button is still pressed. When the up/down button is
released, this gets set to FALSE, and we scroll until the minimum
distance falls below 0. */
gboolean button_pressed;
};
struct _EVScrolledBarClass
{
GtkBinClass parent_class;
};
GtkType e_vscrolled_bar_get_type (void);
GtkWidget* e_vscrolled_bar_new (GtkAdjustment *adjustment);
GtkAdjustment* e_vscrolled_bar_get_adjustment (EVScrolledBar *vscrolled_bar);
void e_vscrolled_bar_set_adjustment (EVScrolledBar *vscrolled_bar,
GtkAdjustment *adjustment);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_VSCROLLED_BAR_H_ */

View File

@ -0,0 +1,445 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Author :
* Damon Chaplin <damon@gtk.org>
*
* Copyright 1999, Helix Code, Inc.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
/*
* This tests the ShortcutBar widget.
*/
#include <gnome.h>
#include "e-shortcut-bar.h"
#define NUM_SHORTCUT_TYPES 5
gchar *shortcut_types[] = {
"folder:", "file:", "calendar:", "todo:", "contacts:"
};
GtkWidget *main_label;
static void quit (GtkWidget *window, GdkEvent *event, gpointer data);
static void add_test_groups (EShortcutBar *shortcut_bar);
static void add_test_group (EShortcutBar *shortcut_bar, gint i,
gchar *group_name);
static gint get_random_int (gint max);
static void on_shortcut_bar_item_selected (EShortcutBar *shortcut_bar,
GdkEvent *event,
gint group_num,
gint item_num);
static void show_standard_popup (EShortcutBar *shortcut_bar,
GdkEvent *event,
gint group_num);
static void show_context_popup (EShortcutBar *shortcut_bar,
GdkEvent *event,
gint group_num,
gint item_num);
static void set_large_icons (GtkWidget *menuitem,
EShortcutBar *shortcut_bar);
static void set_small_icons (GtkWidget *menuitem,
EShortcutBar *shortcut_bar);
static void remove_group (GtkWidget *menuitem,
EShortcutBar *shortcut_bar);
static void rename_item (GtkWidget *menuitem,
EShortcutBar *shortcut_bar);
static void remove_item (GtkWidget *menuitem,
EShortcutBar *shortcut_bar);
int
main (int argc, char *argv[])
{
GtkWidget *window, *hpaned, *shortcut_bar;
gnome_init ("test-shortcut-bar", "0.1", argc, argv);
gtk_widget_push_visual (gdk_imlib_get_visual ());
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
window = gnome_app_new ("TestShortcutBar", "TestShortCutBar");
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
gtk_signal_connect (GTK_OBJECT (window), "delete-event",
GTK_SIGNAL_FUNC (quit), NULL);
hpaned = gtk_hpaned_new ();
gnome_app_set_contents (GNOME_APP (window), hpaned);
gtk_widget_show (hpaned);
shortcut_bar = e_shortcut_bar_new ();
gtk_paned_pack1 (GTK_PANED (hpaned), shortcut_bar, FALSE, TRUE);
gtk_widget_show (shortcut_bar);
#if 0
gtk_container_set_border_width (GTK_CONTAINER (shortcut_bar), 4);
#endif
gtk_paned_set_position (GTK_PANED (hpaned), 100);
/*gtk_paned_set_gutter_size (GTK_PANED (hpaned), 12);*/
main_label = gtk_label_new ("Main Application Window Goes Here");
gtk_paned_pack2 (GTK_PANED (hpaned), main_label, TRUE, TRUE);
gtk_widget_show (main_label);
gtk_widget_pop_visual ();
gtk_widget_pop_colormap ();
add_test_groups (E_SHORTCUT_BAR (shortcut_bar));
gtk_signal_connect (GTK_OBJECT (shortcut_bar), "item_selected",
GTK_SIGNAL_FUNC (on_shortcut_bar_item_selected),
NULL);
gtk_widget_show (window);
gtk_main ();
return 0;
}
static void
quit (GtkWidget *window, GdkEvent *event, gpointer data)
{
gtk_widget_destroy (window);
gtk_exit (0);
}
static void
add_test_groups (EShortcutBar *shortcut_bar)
{
add_test_group (shortcut_bar, 1, "Shortcuts");
add_test_group (shortcut_bar, 2, "My Shortcuts");
add_test_group (shortcut_bar, 3, "Longer Shortcuts");
add_test_group (shortcut_bar, 4, "Very Long Shortcuts");
add_test_group (shortcut_bar, 5, "Incredibly Long Shortcuts");
}
static void
add_test_group (EShortcutBar *shortcut_bar, gint i, gchar *group_name)
{
gint group_num, item_num, num_items;
gchar buffer[128];
gint shortcut_type, j;
group_num = e_shortcut_bar_add_group (E_SHORTCUT_BAR (shortcut_bar),
group_name);
if (group_num % 2)
e_shortcut_bar_set_view_type (E_SHORTCUT_BAR (shortcut_bar),
group_num,
E_ICON_BAR_SMALL_ICONS);
num_items = get_random_int (5) + 3;
for (j = 1; j <= num_items; j++) {
if (j == 1)
sprintf (buffer, "A very long shortcut with proper words so I can test the wrapping and ellipsis behaviour");
else if (j == 2)
sprintf (buffer, "A very long shortcut with averylongworkinthemiddlesoIcantestthewrappingandellipsisbehaviour");
else
sprintf (buffer, "Item %i:%i\n", i, j);
shortcut_type = get_random_int (NUM_SHORTCUT_TYPES);
item_num = e_shortcut_bar_add_item (E_SHORTCUT_BAR (shortcut_bar), group_num, shortcut_types[shortcut_type], buffer);
}
}
/* Returns a random integer between 0 and max - 1. */
static gint
get_random_int (gint max)
{
gint random_num;
random_num = (int) (max * (rand () / (RAND_MAX + 1.0)));
#if 0
g_print ("Random num (%i): %i\n", max, random_num);
#endif
return random_num;
}
static void
on_shortcut_bar_item_selected (EShortcutBar *shortcut_bar,
GdkEvent *event, gint group_num, gint item_num)
{
gchar buffer[256];
if (event->button.button == 1) {
sprintf (buffer, "Item Selected - %i:%i",
group_num + 1, item_num + 1);
gtk_label_set_text (GTK_LABEL (main_label), buffer);
} else if (event->button.button == 3) {
if (item_num == -1)
show_standard_popup (shortcut_bar, event, group_num);
else
show_context_popup (shortcut_bar, event, group_num,
item_num);
}
}
static void
show_standard_popup (EShortcutBar *shortcut_bar,
GdkEvent *event,
gint group_num)
{
GtkWidget *menu, *menuitem;
/* We don't have any commands if there aren't any groups yet. */
if (group_num == -1)
return;
menu = gtk_menu_new ();
menuitem = gtk_menu_item_new_with_label ("Large Icons");
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (set_large_icons), shortcut_bar);
menuitem = gtk_menu_item_new_with_label ("Small Icons");
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (set_small_icons), shortcut_bar);
menuitem = gtk_menu_item_new ();
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("Add New Group");
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("Remove Group");
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (remove_group), shortcut_bar);
menuitem = gtk_menu_item_new_with_label ("Rename Group");
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new ();
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("Add Shortcut...");
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new ();
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("Hide Shortcut Bar");
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
/* Save the group num so we can get it in the callbacks. */
gtk_object_set_data (GTK_OBJECT (menu), "group_num",
GINT_TO_POINTER (group_num));
/* FIXME: Destroy menu when finished with it somehow? */
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
event->button.button, event->button.time);
}
static void
set_large_icons (GtkWidget *menuitem,
EShortcutBar *shortcut_bar)
{
GtkWidget *menu;
gint group_num;
menu = menuitem->parent;
g_return_if_fail (GTK_IS_MENU (menu));
group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu),
"group_num"));
e_shortcut_bar_set_view_type (shortcut_bar, group_num,
E_ICON_BAR_LARGE_ICONS);
}
static void
set_small_icons (GtkWidget *menuitem,
EShortcutBar *shortcut_bar)
{
GtkWidget *menu;
gint group_num;
menu = menuitem->parent;
g_return_if_fail (GTK_IS_MENU (menu));
group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu),
"group_num"));
e_shortcut_bar_set_view_type (shortcut_bar, group_num,
E_ICON_BAR_SMALL_ICONS);
}
static void
remove_group (GtkWidget *menuitem,
EShortcutBar *shortcut_bar)
{
GtkWidget *menu;
gint group_num;
menu = menuitem->parent;
g_return_if_fail (GTK_IS_MENU (menu));
group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu),
"group_num"));
e_shortcut_bar_remove_group (shortcut_bar, group_num);
}
static void
show_context_popup (EShortcutBar *shortcut_bar,
GdkEvent *event,
gint group_num,
gint item_num)
{
GtkWidget *menu, *menuitem, *label, *pixmap;
menu = gtk_menu_new ();
menuitem = gtk_pixmap_menu_item_new ();
label = gtk_label_new ("Open Folder");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_widget_show (label);
gtk_container_add (GTK_CONTAINER (menuitem), label);
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
pixmap = gnome_stock_pixmap_widget (menu, GNOME_STOCK_MENU_OPEN);
if (pixmap) {
gtk_widget_show(pixmap);
gtk_pixmap_menu_item_set_pixmap (GTK_PIXMAP_MENU_ITEM (menuitem), pixmap);
}
menuitem = gtk_menu_item_new_with_label ("Open in New Window");
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("Advanced Find");
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new ();
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("Remove from Shortcut Bar");
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (remove_item), shortcut_bar);
menuitem = gtk_menu_item_new_with_label ("Rename Shortcut");
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
GTK_SIGNAL_FUNC (rename_item), shortcut_bar);
menuitem = gtk_menu_item_new ();
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
menuitem = gtk_menu_item_new_with_label ("Properties");
gtk_widget_set_sensitive (menuitem, FALSE);
gtk_widget_show (menuitem);
gtk_menu_append (GTK_MENU (menu), menuitem);
/* Save the group & item nums so we can get them in the callbacks. */
gtk_object_set_data (GTK_OBJECT (menu), "group_num",
GINT_TO_POINTER (group_num));
gtk_object_set_data (GTK_OBJECT (menu), "item_num",
GINT_TO_POINTER (item_num));
/* FIXME: Destroy menu when finished with it somehow? */
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
event->button.button, event->button.time);
}
static void
rename_item (GtkWidget *menuitem,
EShortcutBar *shortcut_bar)
{
GtkWidget *menu;
gint group_num, item_num;
menu = menuitem->parent;
g_return_if_fail (GTK_IS_MENU (menu));
group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu),
"group_num"));
item_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu),
"item_num"));
e_shortcut_bar_start_editing_item (shortcut_bar, group_num, item_num);
}
static void
remove_item (GtkWidget *menuitem,
EShortcutBar *shortcut_bar)
{
GtkWidget *menu;
gint group_num, item_num;
menu = menuitem->parent;
g_return_if_fail (GTK_IS_MENU (menu));
group_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu),
"group_num"));
item_num = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (menu),
"item_num"));
e_shortcut_bar_remove_item (shortcut_bar, group_num, item_num);
}

View File

@ -1,43 +0,0 @@
/*
* Test code for the ETable package
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <gnome.h>
#include "e-cursors.h"
#include "table-test.h"
int
main (int argc, char *argv [])
{
if (isatty (0)){
int fd;
close (0);
fd = open ("sample.table", O_RDONLY);
if (fd == -1){
fprintf (stderr, "Could not find sample.table, try feeding a table on stdin");
exit (1);
}
dup2 (fd, 0);
}
gnome_init ("TableTest", "TableTest", argc, argv);
e_cursors_init ();
table_browser_test ();
multi_cols_test ();
check_test ();
e_table_test ();
gtk_main ();
e_cursors_shutdown ();
return 0;
}

View File

@ -1,4 +0,0 @@
void table_browser_test (void);
void multi_cols_test (void);
void check_test (void);
void e_table_test (void);

View File

@ -14,7 +14,7 @@
#include <gdk/gdkkeysyms.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-cell-checkbox.h"
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-item.h"
#include "check-empty.xpm"

View File

@ -15,7 +15,7 @@
#include <libgnomeui/gnome-canvas.h>
#include <stdio.h>
#include "e-cell-text.h"
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()

View File

@ -14,7 +14,7 @@
#include <gdk/gdkkeysyms.h>
#include <libgnomeui/gnome-canvas.h>
#include "e-cell-toggle.h"
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-item.h"
#define PARENT_TYPE e_cell_get_type()

View File

@ -8,7 +8,7 @@
*/
#include <config.h>
#include "e-cell.h"
#include "e-util.h"
#include <e-util/e-util.h>
#define PARENT_TYPE gtk_object_get_type()

View File

@ -10,7 +10,7 @@
#include <gtk/gtkobject.h>
#include <gtk/gtksignal.h>
#include "e-table-col.h"
#include "e-util.h"
#include <e-util/e-util.h>
#define PARENT_TYPE (gtk_object_get_type ())

View File

@ -12,7 +12,7 @@
#include "e-table-group.h"
#include "e-table-item.h"
#include <libgnomeui/gnome-canvas-rect-ellipse.h>
#include "e-util.h"
#include <e-util/e-util.h>
#define TITLE_HEIGHT 16
#define GROUP_INDENT 10

View File

@ -8,7 +8,7 @@
*/
#include <config.h>
#include <stdlib.h>
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-sorted.h"
#define PARENT_TYPE E_TABLE_SUBSET_TYPE

View File

@ -9,7 +9,7 @@
#include <config.h>
#include <stdlib.h>
#include <gtk/gtksignal.h>
#include "e-util.h"
#include <e-util/e-util.h>
#include "e-table-subset.h"
#define PARENT_TYPE E_TABLE_MODEL_TYPE

View File

@ -14,8 +14,8 @@
#include <stdio.h>
#include <libgnomeui/gnome-canvas.h>
#include <gtk/gtksignal.h>
#include <e-util/e-util.h>
#include "e-table.h"
#include "e-util.h"
#include "e-table-header-item.h"
#include "e-table-subset.h"
#include "e-table-item.h"

View File

@ -1,153 +0,0 @@
/*
* Test code for the ETable package
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <gnome.h>
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-item.h"
#include "e-cursors.h"
#include "e-cell-text.h"
#include "e-cell-checkbox.h"
#include "table-test.h"
#define LINES 4
static struct {
int value;
char *string;
} my_table [LINES] = {
{ 0, "Buy food" },
{ 1, "Breathe " },
{ 0, "Cancel gdb session with shrink" },
{ 1, "Make screenshots" },
};
/*
* ETableSimple callbacks
*/
static int
col_count (ETableModel *etc, void *data)
{
return 2;
}
static int
row_count (ETableModel *etc, void *data)
{
return LINES;
}
static void *
value_at (ETableModel *etc, int col, int row, void *data)
{
g_assert (col < 2);
g_assert (row < LINES);
if (col == 0)
return GINT_TO_POINTER (my_table [row].value);
else
return my_table [row].string;
}
static void
set_value_at (ETableModel *etc, int col, int row, const void *val, void *data)
{
g_assert (col < 2);
g_assert (row < LINES);
if (col == 0){
my_table [row].value = GPOINTER_TO_INT (val);
printf ("Value at %d,%d set to %d\n", col, row, GPOINTER_TO_INT (val));
} else {
my_table [row].string = g_strdup (val);
printf ("Value at %d,%d set to %s\n", col, row, (char *) val);
}
}
static gboolean
is_cell_editable (ETableModel *etc, int col, int row, void *data)
{
return TRUE;
}
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
}
void
check_test (void)
{
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_check;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, NULL);
/*
* Header
*/
e_table_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT);
cell_image_check = e_cell_checkbox_new ();
col_0 = e_table_col_new (0, "", 18, 18, cell_image_check, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 0);
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
e_table_header_add_column (e_table_header, col_1, 1);
/*
* GUI
*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
canvas = gnome_canvas_new ();
gtk_signal_connect (GTK_OBJECT (canvas), "size_allocate",
GTK_SIGNAL_FUNC (set_canvas_size), NULL);
gtk_container_add (GTK_CONTAINER (window), canvas);
gtk_widget_show_all (window);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
"ETableHeader", e_table_header,
"x", 0,
"y", 0,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
"x", (double) 0,
"y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
}

View File

@ -1,196 +0,0 @@
/*
* Test code for the ETable package
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <gnome.h>
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-item.h"
#include "e-cursors.h"
#include "e-cell-text.h"
#include "e-cell-toggle.h"
#include "table-test.h"
#define LINES 4
static struct {
int value;
char *string;
} my_table [LINES] = {
{ 0, "You are not" },
{ 1, "A beautiful and unique " },
{ 0, "Snowflake" },
{ 2, "You are not your wallet" },
};
/*
* ETableSimple callbacks
*/
static int
col_count (ETableModel *etc, void *data)
{
return 2;
}
static int
row_count (ETableModel *etc, void *data)
{
return LINES;
}
static void *
value_at (ETableModel *etc, int col, int row, void *data)
{
g_assert (col < 2);
g_assert (row < LINES);
if (col == 0)
return GINT_TO_POINTER (my_table [row].value);
else
return my_table [row].string;
}
static void
set_value_at (ETableModel *etc, int col, int row, const void *val, void *data)
{
g_assert (col < 2);
g_assert (row < LINES);
if (col == 0){
my_table [row].value = GPOINTER_TO_INT (val);
printf ("Value at %d,%d set to %d\n", col, row, GPOINTER_TO_INT (val));
} else {
my_table [row].string = g_strdup (val);
printf ("Value at %d,%d set to %s\n", col, row, (char *) val);
}
}
static gboolean
is_cell_editable (ETableModel *etc, int col, int row, void *data)
{
return TRUE;
}
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
}
void
multi_cols_test (void)
{
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header, *e_table_header_multiple;
ETableCol *col_0, *col_1;
ECell *cell_left_just, *cell_image_toggle;
gtk_widget_push_visual (gdk_rgb_get_visual ());
gtk_widget_push_colormap (gdk_rgb_get_cmap ());
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, NULL);
/*
* Header
*/
e_table_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT);
{
GdkPixbuf **images = g_new (GdkPixbuf *, 3);
int i;
images [0] = gdk_pixbuf_new_from_file ("image1.png");
images [1] = gdk_pixbuf_new_from_file ("image2.png");
images [2] = gdk_pixbuf_new_from_file ("image3.png");
cell_image_toggle = e_cell_toggle_new (0, 3, images);
for (i = 0; i < 3; i++)
gdk_pixbuf_unref (images [i]);
g_free (images);
}
col_1 = e_table_col_new (1, "Item Name", 180, 20, cell_left_just, g_str_equal, TRUE);
e_table_header_add_column (e_table_header, col_1, 0);
col_0 = e_table_col_new (0, "A", 48, 48, cell_image_toggle, g_int_equal, TRUE);
e_table_header_add_column (e_table_header, col_0, 1);
/*
* Second test
*/
e_table_header_multiple = e_table_header_new ();
e_table_header_add_column (e_table_header_multiple, col_0, 0);
e_table_header_add_column (e_table_header_multiple, col_1, 1);
e_table_header_add_column (e_table_header_multiple, col_1, 2);
/*
* GUI
*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
canvas = gnome_canvas_new ();
gtk_signal_connect (GTK_OBJECT (canvas), "size_allocate",
GTK_SIGNAL_FUNC (set_canvas_size), NULL);
gtk_container_add (GTK_CONTAINER (window), canvas);
gtk_widget_show_all (window);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
"ETableHeader", e_table_header,
"x", 0,
"y", 0,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
"x", (double) 0,
"y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
"ETableHeader", e_table_header_multiple,
"x", 300,
"y", 0,
NULL);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_item_get_type (),
"ETableHeader", e_table_header_multiple,
"ETableModel", e_table_model,
"x", (double) 300,
"y", (double) 30,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
}

View File

@ -1,304 +0,0 @@
/*
* Test code for the ETable package
*
* Author:
* Miguel de Icaza (miguel@gnu.org)
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <gnome.h>
#include "e-table-simple.h"
#include "e-table-header.h"
#include "e-table-header-item.h"
#include "e-table-item.h"
#include "e-cursors.h"
#include "e-cell-text.h"
#include "e-table.h"
#include "table-test.h"
char buffer [1024];
char **column_labels;
char ***table_data;
int cols = 0;
int lines = 0;
int lines_alloc = 0;
static void
parse_headers ()
{
char *p, *s;
int in_value = 0, i;
fgets (buffer, sizeof (buffer)-1, stdin);
for (p = buffer; *p; p++){
if (*p == ' ' || *p == '\t'){
if (in_value){
cols++;
in_value = 0;
}
} else
in_value = 1;
}
if (in_value)
cols++;
if (!cols){
fprintf (stderr, "No columns in first row\n");
exit (1);
}
column_labels = g_new0 (char *, cols);
p = buffer;
for (i = 0; (s = strtok (p, " \t")) != NULL; i++){
column_labels [i] = g_strdup (s);
p = NULL;
}
printf ("%d headers:\n", cols);
for (i = 0; i < cols; i++){
printf ("header %d: %s\n", i, column_labels [i]);
}
}
static char **
load_line (char *buffer, int cols)
{
char **line = g_new0 (char *, cols);
char *p;
int i;
for (i = 0; i < cols; i++){
p = strtok (buffer, " \t\n");
if (p == NULL){
for (; i < cols; i++)
line [i] = g_strdup ("");
return line;
} else
line [i] = g_strdup (p);
buffer = NULL;
}
return line;
}
static void
append_line (char **line)
{
if (lines <= lines_alloc){
lines_alloc = lines + 50;
table_data = g_renew (char **, table_data, lines_alloc);
}
table_data [lines] = line;
lines++;
}
static void
load_data ()
{
int i;
{
static int loaded;
if (loaded)
return;
loaded = TRUE;
}
parse_headers ();
while (fgets (buffer, sizeof (buffer)-1, stdin) != NULL){
char **line;
if (buffer [0] == '\n')
continue;
line = load_line (buffer, cols);
append_line (line);
}
for (i = 0; i < lines; i++){
int j;
printf ("Line %d: ", i);
for (j = 0; j < cols; j++)
printf ("[%s] ", table_data [i][j]);
printf ("\n");
}
}
/*
* ETableSimple callbacks
*/
static int
col_count (ETableModel *etc, void *data)
{
return cols;
}
static int
row_count (ETableModel *etc, void *data)
{
return lines;
}
static void *
value_at (ETableModel *etc, int col, int row, void *data)
{
g_assert (col < cols);
g_assert (row < lines);
return (void *) table_data [row][col];
}
static void
set_value_at (ETableModel *etc, int col, int row, const void *val, void *data)
{
g_assert (col < cols);
g_assert (row < lines);
g_free (table_data [row][col]);
table_data [row][col] = g_strdup (val);
printf ("Value at %d,%d set to %s\n", col, row, (char *) val);
}
static gboolean
is_cell_editable (ETableModel *etc, int col, int row, void *data)
{
return TRUE;
}
static void
set_canvas_size (GnomeCanvas *canvas, GtkAllocation *alloc)
{
gnome_canvas_set_scroll_region (canvas, 0, 0, alloc->width, alloc->height);
}
void
table_browser_test (void)
{
GtkWidget *canvas, *window;
ETableModel *e_table_model;
ETableHeader *e_table_header;
ECell *cell_left_just;
GnomeCanvasItem *group;
int i;
load_data ();
/*
* Data model
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, NULL);
/*
* Header
*/
e_table_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT);
for (i = 0; i < cols; i++){
ETableCol *ecol = e_table_col_new (
i, column_labels [i],
80, 20, cell_left_just,
g_str_equal, TRUE);
e_table_header_add_column (e_table_header, ecol, i);
}
/*
* Setup GUI
*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
canvas = gnome_canvas_new ();
gtk_signal_connect (GTK_OBJECT (canvas), "size_allocate",
GTK_SIGNAL_FUNC (set_canvas_size), NULL);
gtk_container_add (GTK_CONTAINER (window), canvas);
gtk_widget_show_all (window);
gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
e_table_header_item_get_type (),
"ETableHeader", e_table_header,
"x", 0,
"y", 0,
NULL);
group = gnome_canvas_item_new (
gnome_canvas_root (GNOME_CANVAS (canvas)),
gnome_canvas_group_get_type (),
"x", 30.0,
"y", 30.0,
NULL);
gnome_canvas_item_new (
GNOME_CANVAS_GROUP (group),
e_table_item_get_type (),
"ETableHeader", e_table_header,
"ETableModel", e_table_model,
"x", (double) 0,
"y", (double) 0,
"drawgrid", TRUE,
"drawfocus", TRUE,
"spreadsheet", TRUE,
NULL);
}
static void
do_e_table_demo (const char *col_spec, const char *group_spec)
{
GtkWidget *e_table, *window;
ETableModel *e_table_model;
ECell *cell_left_just;
ETableHeader *full_header;
int i;
/*
* Data model
*/
e_table_model = e_table_simple_new (
col_count, row_count, value_at,
set_value_at, is_cell_editable, NULL);
full_header = e_table_header_new ();
cell_left_just = e_cell_text_new (e_table_model, NULL, GTK_JUSTIFY_LEFT);
for (i = 0; i < cols; i++){
ETableCol *ecol = e_table_col_new (
i, column_labels [i],
80, 20, cell_left_just,
g_str_equal, TRUE);
e_table_header_add_column (full_header, ecol, i);
}
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
e_table = e_table_new (full_header, e_table_model, col_spec, group_spec);
gtk_container_add (GTK_CONTAINER (window), e_table);
gtk_widget_set_usize (window, 200, 200);
gtk_widget_show (e_table);
gtk_widget_show (window);
}
void
e_table_test (void)
{
load_data ();
if (getenv ("DO")){
do_e_table_demo ("0,1,2,3,4", NULL);
do_e_table_demo ("0,1,2,3,4", "3,4");
}
do_e_table_demo ("0,1,2,3,4", "3");
}

View File

@ -1,17 +0,0 @@
#include <config.h>
#include "e-table-simple.h"
struct {
char *str;
int val;
} data [] = {
{ "Miguel", 10 },
{ "Nat", 20 },
{ NULL, 0 },
};
main ()
{
}