root / trunk / linux / toolbar.cpp

Revision 726, 32.1 kB (checked in by leo, 6 months ago)

Fixed linux color selection.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1// Toolbar creation and related functions
2//
3
4#include <gdk/gdkkeysyms.h>
5#include <gtk/gtk.h>
6#include <stdio.h>
7#include "opengl.h"
8#include "gtktools.h"
9#include "main.h"
10#include "globals.h" 
11#include "project.h"
12#include "pieceinf.h"
13#include "toolbar.h"
14#include "lc_message.h"
15#include "preview.h"
16#include "library.h"
17#include "lc_application.h"
18#include "lc_colors.h"
19
20// =============================================================================
21// Variables
22
23GtkWidget *piecetree;
24GtkWidget *pieceentry;
25GtkWidget *piecemenu;
26GtkWidget *colorlist;
27GtkWidget *grouptoolbar;
28PiecePreview *preview;
29
30TOOL_TOOLBAR tool_toolbar;
31MAIN_TOOLBAR main_toolbar;
32ANIM_TOOLBAR anim_toolbar;
33
34// =========================================================
35
36void create_toolbars(GtkWidget *window, GtkWidget *vbox)
37{
38#include "pixmaps/ac-brick.xpm"
39#include "pixmaps/ac-light.xpm"
40#include "pixmaps/ac-spot.xpm"
41#include "pixmaps/ac-cam.xpm"
42#include "pixmaps/ac-sel.xpm"
43#include "pixmaps/ac-move.xpm"
44#include "pixmaps/ac-rot.xpm"
45#include "pixmaps/ac-erase.xpm"
46#include "pixmaps/ac-paint.xpm"
47#include "pixmaps/ac-zoom.xpm"
48#include "pixmaps/ac-pan.xpm"
49#include "pixmaps/ac-rotv.xpm"
50#include "pixmaps/ac-roll.xpm"
51#include "pixmaps/ac-zoomr.xpm"
52#include "pixmaps/ac-zoome.xpm"
53#include "pixmaps/ac-prev.xpm"
54#include "pixmaps/ac-next.xpm"
55#include "pixmaps/an-anim.xpm"
56#include "pixmaps/an-key.xpm"
57#include "pixmaps/an-next.xpm"
58#include "pixmaps/an-prev.xpm"
59#include "pixmaps/an-first.xpm"
60#include "pixmaps/an-last.xpm"
61#include "pixmaps/an-play.xpm"
62#include "pixmaps/an-stop.xpm"
63#include "pixmaps/st-about.xpm"
64#include "pixmaps/st-fast.xpm"
65#include "pixmaps/st-paste.xpm"
66#include "pixmaps/st-save.xpm"
67#include "pixmaps/st-help.xpm"
68#include "pixmaps/st-prev.xpm"
69#include "pixmaps/st-snap.xpm"
70#include "pixmaps/st-copy.xpm"
71#include "pixmaps/st-new.xpm"
72#include "pixmaps/st-print.xpm"
73#include "pixmaps/st-snapa.xpm"
74#include "pixmaps/st-cut.xpm"
75#include "pixmaps/st-open.xpm"
76#include "pixmaps/st-redo.xpm"
77#include "pixmaps/st-undo.xpm"
78
79  GtkWidget *button;
80
81  // Main Toolbar
82  main_toolbar.handle_box = gtk_handle_box_new ();
83  gtk_box_pack_start (GTK_BOX (vbox), main_toolbar.handle_box, FALSE, FALSE, 0);
84  //  if (user_rc.view_main_toolbar)
85    gtk_widget_show (main_toolbar.handle_box);
86  main_toolbar.toolbar = gtk_toolbar_new ();
87  gtk_toolbar_set_orientation(GTK_TOOLBAR(main_toolbar.toolbar), GTK_ORIENTATION_HORIZONTAL);
88  gtk_toolbar_set_style(GTK_TOOLBAR(main_toolbar.toolbar), GTK_TOOLBAR_ICONS);
89  //  gtk_toolbar_set_style (GTK_TOOLBAR (main_toolbar.toolbar), user_rc.toolbar_style);
90  gtk_container_add (GTK_CONTAINER (main_toolbar.handle_box), main_toolbar.toolbar);
91  gtk_widget_show (main_toolbar.toolbar);
92
93  gtk_container_border_width (GTK_CONTAINER (main_toolbar.toolbar), 2);
94  //  gtk_toolbar_set_button_relief (GTK_TOOLBAR (main_toolbar.toolbar), GTK_RELIEF_NONE);
95  //  gtk_toolbar_set_space_style (GTK_TOOLBAR (main_toolbar.toolbar), GTK_TOOLBAR_SPACE_LINE);
96  //  gtk_toolbar_set_space_size (GTK_TOOLBAR (main_toolbar.toolbar), 10);
97
98  gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "New",
99     "Create a new project", "", new_pixmap (window, st_new),
100     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_FILE_NEW);
101  gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Open",
102     "Open an existing project", "", new_pixmap (window, st_open),
103     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_FILE_OPEN);
104  gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Save",
105     "Save the active project", "", new_pixmap (window, st_save),
106     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_FILE_SAVE);
107  button = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Print",
108     " ", "", new_pixmap (window, st_print), GTK_SIGNAL_FUNC (OnCommand), NULL);
109  gtk_widget_set_sensitive (button, FALSE);
110  button = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Preview",
111     " ", "", new_pixmap (window, st_prev), GTK_SIGNAL_FUNC (OnCommand), NULL);
112  gtk_widget_set_sensitive (button, FALSE);
113  main_toolbar.cut = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Cut",
114     "Cut the selection", "", new_pixmap (window, st_cut),
115     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_EDIT_CUT);
116  main_toolbar.copy = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Copy",
117     "Copy the selection", "", new_pixmap (window, st_copy),
118     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_EDIT_COPY);
119  main_toolbar.paste = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Paste",
120     "Insert Clipboard contents", "", new_pixmap (window, st_paste),
121      GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_EDIT_PASTE);
122  main_toolbar.undo = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Undo",
123     "Undo last action", "", new_pixmap (window, st_undo),
124     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_EDIT_UNDO);
125  main_toolbar.redo = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Redo",
126     "Redo the last undone action", "", new_pixmap (window, st_redo),
127      GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_EDIT_REDO);
128  main_toolbar.snap = gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Snap",
129     "Toggle 3D snap", "", new_pixmap (window, st_snap), GTK_SIGNAL_FUNC (OnCommand), NULL);
130  main_toolbar.angle = gtk_toolbar_append_element (GTK_TOOLBAR (main_toolbar.toolbar),
131     GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL, "Angle", "Toggle angle snap", "",
132     new_pixmap (window, st_snapa), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_SNAP_A);
133  main_toolbar.fast = gtk_toolbar_append_element (GTK_TOOLBAR (main_toolbar.toolbar),
134     GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL, "Fast", "Fast rendering", "",
135     new_pixmap (window, st_fast), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_TOOLBAR_FASTRENDER);
136  gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "About", "About LeoCAD", "",
137     new_pixmap (window, st_about), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_HELP_ABOUT);
138  gtk_toolbar_append_item (GTK_TOOLBAR (main_toolbar.toolbar), "Help", "Help", "",
139     new_pixmap (window, st_help), GTK_SIGNAL_FUNC (OnCommand), NULL);
140  gtk_widget_set_sensitive (button, FALSE);
141
142  // Tools Toolbar
143  tool_toolbar.handle_box = gtk_handle_box_new ();
144  gtk_box_pack_start (GTK_BOX (vbox),tool_toolbar. handle_box, FALSE, FALSE, 0);
145  //  if (user_rc.view_tool_toolbar)
146    gtk_widget_show (tool_toolbar.handle_box);
147
148  tool_toolbar.toolbar = gtk_toolbar_new();
149  gtk_toolbar_set_orientation(GTK_TOOLBAR(tool_toolbar.toolbar), GTK_ORIENTATION_HORIZONTAL);
150  gtk_toolbar_set_style(GTK_TOOLBAR(tool_toolbar.toolbar), GTK_TOOLBAR_ICONS);
151  //  gtk_toolbar_set_style (GTK_TOOLBAR (tool_toolbar.toolbar), user_rc.toolbar_style);
152  gtk_container_add (GTK_CONTAINER (tool_toolbar.handle_box), tool_toolbar.toolbar);
153  gtk_widget_show (tool_toolbar.toolbar);
154
155  gtk_container_border_width (GTK_CONTAINER (tool_toolbar.toolbar), 2);
156  //  gtk_toolbar_set_button_relief (GTK_TOOLBAR (tool_toolbar.toolbar), GTK_RELIEF_NONE);
157
158  tool_toolbar.brick = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
159     GTK_TOOLBAR_CHILD_RADIOBUTTON, NULL, "Piece", "Insert Piece", "",
160     new_pixmap (window, ac_brick), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_INSERT);
161  tool_toolbar.light = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
162     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Light", "Insert Light", "",
163     new_pixmap (window, ac_light), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_LIGHT);
164  tool_toolbar.spot = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
165     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Spot", "Insert Spotlight", "",
166     new_pixmap (window, ac_spot), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_SPOTLIGHT);
167  tool_toolbar.camera = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
168     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Camera", "Insert Camera", "",
169     new_pixmap (window, ac_cam),  GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_CAMERA);
170  tool_toolbar.select = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
171     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Select", "Select Objects", "",
172     new_pixmap (window, ac_sel), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_SELECT);
173  tool_toolbar.move = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
174     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Move", "Move Objects", "",
175     new_pixmap (window, ac_move), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_MOVE);
176  tool_toolbar.rotate = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
177     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Rotate", "Rotate Pieces", "",
178     new_pixmap (window, ac_rot), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROTATE);
179  tool_toolbar.erase = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
180     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Delete", "Remove Objects", "",
181     new_pixmap (window, ac_erase), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ERASER);
182  tool_toolbar.paint = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
183     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Paint", "Paint Bricks", "",
184     new_pixmap (window, ac_paint), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_PAINT);
185  tool_toolbar.zoom = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
186     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Zoom", "Zoom", "",
187     new_pixmap (window, ac_zoom), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ZOOM);
188  tool_toolbar.pan = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
189     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Pan", "Pan", "",
190     new_pixmap (window, ac_pan), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_PAN);
191  tool_toolbar.rotview = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
192     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Rot. View", "Rotate View", "",
193     new_pixmap (window, ac_rotv), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROTATE_VIEW);
194  tool_toolbar.roll = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
195     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Roll", "Roll", "",
196     new_pixmap (window, ac_roll), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ROLL);
197  tool_toolbar.zoomreg = button = gtk_toolbar_append_element (GTK_TOOLBAR (tool_toolbar.toolbar),
198     GTK_TOOLBAR_CHILD_RADIOBUTTON, button, "Zoom Box", "Zoom Region", "",
199     new_pixmap (window, ac_zoomr), GTK_SIGNAL_FUNC (OnCommand), (void*)ID_ACTION_ZOOM_REGION);
200  gtk_toolbar_append_item (GTK_TOOLBAR (tool_toolbar.toolbar), "Zoom Ext.", "Zoom Extents", "",
201     new_pixmap (window, ac_zoome), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_ZOOMEXTENTS);
202  tool_toolbar.prev = gtk_toolbar_append_item (GTK_TOOLBAR (tool_toolbar.toolbar), "Show Previous", "Show piece on previous step", "",
203     new_pixmap (window, ac_prev), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_PIECE_PREVIOUS);
204  tool_toolbar.next = gtk_toolbar_append_item (GTK_TOOLBAR (tool_toolbar.toolbar), "Show Next", "Show Piece on next step", "",
205     new_pixmap (window, ac_next), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_PIECE_NEXT);
206
207  // Animation Toolbar
208  anim_toolbar.handle_box = gtk_handle_box_new ();
209  gtk_box_pack_start (GTK_BOX (vbox), anim_toolbar.handle_box, FALSE, FALSE, 0);
210  //  if (user_rc.view_anim_toolbar)
211    gtk_widget_show (anim_toolbar.handle_box);
212
213  anim_toolbar.toolbar = gtk_toolbar_new();
214  gtk_toolbar_set_orientation(GTK_TOOLBAR(anim_toolbar.toolbar), GTK_ORIENTATION_HORIZONTAL);
215  gtk_toolbar_set_style(GTK_TOOLBAR(anim_toolbar.toolbar), GTK_TOOLBAR_ICONS);
216//  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), user_rc.toolbar_style);
217  gtk_container_add (GTK_CONTAINER (anim_toolbar.handle_box), anim_toolbar.toolbar);
218  gtk_widget_show (anim_toolbar.toolbar);
219
220  gtk_container_border_width (GTK_CONTAINER (anim_toolbar.toolbar), 2);
221  //  gtk_toolbar_set_button_relief (GTK_TOOLBAR (anim_toolbar.toolbar), GTK_RELIEF_NONE);
222
223  anim_toolbar.first = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
224     "First", "Go to the Start", "", new_pixmap (window, an_first),
225     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_STEP_FIRST);
226  anim_toolbar.prev = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
227     "Previous", "Go Back", "", new_pixmap (window, an_prev),
228     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_STEP_PREVIOUS);
229  anim_toolbar.play = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
230     "Play", "Play Animation", "", new_pixmap (window, an_play),
231     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_PLAY);
232  anim_toolbar.stop = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
233     "Stop", "Stop Animation", "", new_pixmap (window, an_stop),
234     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_STOP);
235  anim_toolbar.next = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
236     "Next", "Go Forward", "", new_pixmap (window, an_next),
237     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_STEP_NEXT);
238  anim_toolbar.last = gtk_toolbar_append_item (GTK_TOOLBAR (anim_toolbar.toolbar),
239     "Last", "Go to the End", "", new_pixmap (window, an_last),
240     GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_VIEW_STEP_LAST);
241  anim_toolbar.anim = gtk_toolbar_append_element (GTK_TOOLBAR (anim_toolbar.toolbar),
242     GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL, "Mode", "Toggle Animation or Instructions", "",
243     new_pixmap (window, an_anim), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_TOOLBAR_ANIMATION);
244  anim_toolbar.keys = gtk_toolbar_append_element (GTK_TOOLBAR (anim_toolbar.toolbar),
245     GTK_TOOLBAR_CHILD_TOGGLEBUTTON, NULL, "Keys", "Add Keys", "",
246     new_pixmap (window, an_key), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_TOOLBAR_ADDKEYS);
247}
248
249// =========================================================
250// Pieces toolbar
251
252//static bool list_subparts = false;
253static int cur_color = 0;
254static GdkPixmap* colorlist_pixmap = NULL;
255
256int PiecesSortFunc(const PieceInfo* a, const PieceInfo* b, void* SortData)
257{
258    if (a->IsSubPiece())
259    {
260        if (b->IsSubPiece())
261        {
262            return strcmp(a->m_strDescription, b->m_strDescription);
263        }
264        else
265        {
266            return 1;
267        }
268    }
269    else
270    {
271        if (b->IsSubPiece())
272        {
273            return -1;
274        }
275        else
276        {
277            return strcmp(a->m_strDescription, b->m_strDescription);
278        }
279    }
280
281    return 0;
282}
283
284void fill_piecetree()
285{
286  PiecesLibrary* Lib = lcGetPiecesLibrary();
287  GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(piecetree)));
288
289  for (int i = 0; i < Lib->GetNumCategories(); i++)
290  {
291    GtkTreeIter iter;
292    gtk_tree_store_append(model, &iter, NULL);
293    gtk_tree_store_set(model, &iter, 0, (const char*)Lib->GetCategoryName(i), 1, NULL, -1);
294
295    lcPtrArray<PieceInfo> SinglePieces, GroupedPieces;
296
297    Lib->GetCategoryEntries(i, true, SinglePieces, GroupedPieces);
298
299    SinglePieces += GroupedPieces;
300    SinglePieces.Sort(PiecesSortFunc, NULL);
301
302    for (int j = 0; j < SinglePieces.GetSize(); j++)
303    {
304      PieceInfo* Info = SinglePieces[j];
305
306      GtkTreeIter entry;
307
308      gtk_tree_store_append(model, &entry, &iter);
309      gtk_tree_store_set(model, &entry, 0, Info->m_strDescription, 1, Info, -1);
310
311      if (GroupedPieces.FindIndex(Info) != -1)
312      {
313    lcPtrArray<PieceInfo> Patterns;
314    Lib->GetPatternedPieces(Info, Patterns);
315
316    for (int k = 0; k < Patterns.GetSize(); k++)
317    {
318      GtkTreeIter pat;
319      PieceInfo* child = Patterns[k];
320
321      if (!Lib->PieceInCategory(child, Lib->GetCategoryKeywords(i)))
322        continue;
323
324      const char* desc = child->m_strDescription;
325      int len = strlen(Info->m_strDescription);
326
327      if (!strncmp(child->m_strDescription, Info->m_strDescription, len))
328        desc += len;
329
330      gtk_tree_store_append(model, &pat, &entry);
331      gtk_tree_store_set(model, &pat, 0, desc, 1, child, -1);
332    }   
333      }
334    }
335  }
336
337  GtkTreeIter iter;
338  gtk_tree_store_append(model, &iter, NULL);
339  gtk_tree_store_set(model, &iter, 0, "Search Results", 1, NULL, -1);
340
341  GtkTreeIter entry;
342  gtk_tree_store_append(GTK_TREE_STORE(model), &entry, &iter);
343  gtk_tree_store_set(GTK_TREE_STORE(model), &entry, 0, "No pieces found", 1, NULL, -1);
344}
345
346// Callback for the pieces list.
347static void piecetree_changed(GtkTreeSelection* selection, gpointer data)
348{
349  GtkTreeIter iter;
350  GtkTreeModel* model;
351
352  if (gtk_tree_selection_get_selected(selection, &model, &iter))
353  {
354    gpointer sel;
355
356    gtk_tree_model_get(model, &iter, 1, &sel, -1);
357
358    if (sel)
359      g_App->m_PiecePreview->SetSelection(sel);
360  }
361}
362
363static void piececombo_popup_position (GtkMenu *menu, gint *x, gint *y, gboolean* push, gpointer data)
364{
365  gdk_window_get_origin (pieceentry->window, x, y);
366  *y += pieceentry->allocation.height;
367  *push = true;
368}
369
370static void piececombo_popup (GtkWidget *widget, gpointer data)
371{
372  if (piecemenu != NULL)
373    gtk_menu_popup (GTK_MENU (piecemenu), NULL, NULL, piececombo_popup_position, NULL, 1, GDK_CURRENT_TIME);
374}
375
376static void piececombo_selected (GtkWidget *widget, gpointer data)
377{
378  gchar *str;
379
380  gtk_label_get (GTK_LABEL (GTK_BIN (widget)->child), &str);
381  gtk_entry_set_text (GTK_ENTRY (pieceentry), str);
382}
383
384// Add a new piece to the combobox
385void piececombo_add (const char* str)
386{
387  if (str == NULL)
388  {
389    // Clear the list
390    if (piecemenu != NULL)
391    {
392      gtk_widget_destroy (piecemenu);
393      piecemenu = NULL;
394    }
395  }
396  else
397  {
398    GtkWidget *item;
399    GList *children;
400    int pos = 0;
401
402    if (piecemenu == NULL)
403      piecemenu = gtk_menu_new ();
404
405    children = gtk_container_children (GTK_CONTAINER (piecemenu));
406
407    while (children)
408    {
409      gchar *label;
410      int i;
411
412      gtk_label_get (GTK_LABEL (GTK_BIN (children->data)->child), &label);
413
414      i = strcmp (str, label);
415
416      if (i == 0)
417        return;
418      else if (i < 0)
419        break;
420
421      children = children->next;
422      pos++;
423    }
424
425    item = gtk_menu_item_new_with_label (str);
426    gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (piececombo_selected), NULL);
427    gtk_widget_show (item);
428    gtk_menu_insert (GTK_MENU (piecemenu), item, pos);
429  }
430}
431
432static gint piececombo_key(GtkWidget* widget, GdkEventKey* event)
433{
434  if (event->keyval == GDK_Return)
435  {
436    const gchar* str = gtk_entry_get_text(GTK_ENTRY(pieceentry));
437    PiecesLibrary* Lib = lcGetPiecesLibrary();
438
439    // Save search.
440    int Index = Lib->FindCategoryIndex("Search Results");
441
442    if (Index == -1)
443    {
444      Lib->AddCategory("Search Results", (const char*)str);
445      Index = Lib->GetNumCategories() - 1;
446    }
447    else
448      Lib->SetCategory(Index, "Search Results", (const char*)str);
449
450    // Find search category row.
451    GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(piecetree));
452    GtkTreeIter iter;
453
454    if (!gtk_tree_model_get_iter_first(model, &iter))
455      return FALSE;
456
457    do
458    {
459      gchar* name;
460      gtk_tree_model_get(model, &iter, 0, &name, -1);
461
462      if (strcmp(name, "Search Results"))
463    continue;
464
465      GtkTreeIter child;
466
467      // Remove all children.
468      while (gtk_tree_model_iter_children(model, &child, &iter))
469    gtk_tree_store_remove(GTK_TREE_STORE(model), &child);   
470
471      // Perform search.
472      lcPtrArray<PieceInfo> SinglePieces, GroupedPieces;
473      Lib->GetCategoryEntries(Index, true, SinglePieces, GroupedPieces);
474
475      // Merge and sort the arrays.
476      SinglePieces += GroupedPieces;
477      SinglePieces.Sort(PiecesSortFunc, NULL);
478
479      // Add results.
480      for (int i = 0; i < SinglePieces.GetSize(); i++)
481      {
482    PieceInfo* Info = SinglePieces[i];
483
484    GtkTreeIter entry;
485    gtk_tree_store_append(GTK_TREE_STORE(model), &entry, &iter);
486    gtk_tree_store_set(GTK_TREE_STORE(model), &entry, 0, Info->m_strDescription, 1, Info, -1);
487      }
488
489      if (SinglePieces.GetSize() == 0)
490      {
491    GtkTreeIter entry;
492    gtk_tree_store_append(GTK_TREE_STORE(model), &entry, &iter);
493    gtk_tree_store_set(GTK_TREE_STORE(model), &entry, 0, "No pieces found", 1, NULL, -1);
494     }
495
496      // Expand results.
497      GtkTreePath* path = gtk_tree_model_get_path(model, &iter);
498      gtk_tree_view_expand_row(GTK_TREE_VIEW(piecetree), path, FALSE);
499      gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(piecetree), path, NULL, TRUE, 0.5f, 0.0f);
500      gtk_tree_path_free(path);
501
502    } while (gtk_tree_model_iter_next(model, &iter));
503  }
504
505  return FALSE;
506}
507
508static void piececombo_changed (GtkWidget *widget, gpointer data)
509{
510  PiecesLibrary *pLib = lcGetPiecesLibrary();
511  const gchar* str;
512  int i;
513
514  str = gtk_entry_get_text (GTK_ENTRY (pieceentry));
515
516  for (i = 0; i < pLib->GetPieceCount (); i++)
517  {
518    PieceInfo* pInfo = pLib->GetPieceInfo (i);
519
520    if (strcmp (str, pInfo->m_strDescription) == 0)
521    {
522      // Select the piece
523      //      i = gtk_clist_find_row_from_data (GTK_CLIST (piecelist), pInfo);
524      //      gtk_clist_select_row (GTK_CLIST (piecelist), i, 0);
525      //      if (gtk_clist_row_is_visible (GTK_CLIST (piecelist), i) != GTK_VISIBILITY_FULL)
526      //    gtk_clist_moveto (GTK_CLIST (piecelist), i, 0, 0.5f, 0);
527
528      return;
529    }
530  }
531}
532
533// Draw a pixmap for the colorlist control
534static void colorlist_draw_pixmap(GtkWidget *widget)
535{
536  GdkGC* gc = gdk_gc_new(widget->window);
537  int i;
538  GdkRectangle rect;
539  GdkColor c;
540
541  gdk_gc_set_fill(gc, GDK_SOLID);
542  rect.y = 0;
543  rect.width = widget->allocation.width/14+1;
544  rect.height = widget->allocation.height/2;
545
546  for (i = 0; i < 28; i++)
547  {
548    if (i == 14)
549      rect.y = rect.height;
550
551    if (i < 14)
552      rect.x = widget->allocation.width * i / 14;
553    else
554      rect.x = widget->allocation.width * (i-14) / 14;
555
556    c.red = (gushort)(lcColorList[i].Value[0]*0xFFFF);
557    c.green = (gushort)(lcColorList[i].Value[1]*0xFFFF);
558    c.blue = (gushort)(lcColorList[i].Value[2]*0xFFFF);
559    gdk_color_alloc(gtk_widget_get_colormap(widget), &c);
560    gdk_gc_set_foreground(gc, &c);
561
562    gdk_draw_rectangle (colorlist_pixmap, gc, TRUE,
563              rect.x, rect.y,
564              rect.width, rect.height);
565
566    if (i > 13 && i < 21)
567    {
568      int x, y;
569      gdk_color_white(gtk_widget_get_colormap(widget), &c);
570      gdk_gc_set_foreground(gc, &c);
571     
572      for (x = rect.x; x < rect.x + rect.width; x++)
573      {
574    for (y = rect.y + x%4; y < rect.y + rect.height; y += 4)
575      gdk_draw_point(colorlist_pixmap, gc, x, y);
576
577    for (y = rect.y + rect.height - x%4; y > rect.y; y -= 4)
578      gdk_draw_point(colorlist_pixmap, gc, x, y);
579      }
580    }
581  }
582
583  gdk_color_black(gtk_widget_get_colormap(widget), &c);
584  gdk_gc_set_foreground(gc, &c);
585  gdk_gc_set_line_attributes(gc, 1,
586    GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
587
588  for (i = 0; i < 14; i++)
589    gdk_draw_line (colorlist_pixmap, gc,
590       widget->allocation.width * i / 14, 0,
591       widget->allocation.width * i / 14, widget->allocation.height);
592 
593  gdk_draw_line (colorlist_pixmap, gc, 0, widget->allocation.height-1,
594      widget->allocation.width, widget->allocation.height-1);
595  gdk_draw_line (colorlist_pixmap, gc, 0, widget->allocation.height/2,
596      widget->allocation.width, widget->allocation.height/2);
597  gdk_draw_line (colorlist_pixmap, gc, widget->allocation.width-1, 0,
598      widget->allocation.width-1, widget->allocation.height);
599  gdk_draw_line (colorlist_pixmap, gc, 0, 0, widget->allocation.width, 0);
600
601  c.red = (gushort)(0.4f*0xFFFF);
602  c.green = (gushort)(0.8f*0xFFFF);
603  c.blue = (gushort)(0.4f*0xFFFF);
604  gdk_color_alloc(gtk_widget_get_colormap(widget), &c);
605  gdk_gc_set_foreground(gc, &c);
606
607  int l, r, t, b;
608  i = cur_color;
609  if (i > 13) i -= 14;
610  l = widget->allocation.width * i / 14;
611  r = widget->allocation.width * (i+1) / 14;
612  t = (cur_color < 14) ? 0 : widget->allocation.height/2;
613  b = (cur_color < 14) ? widget->allocation.height/2 : widget->allocation.height-1;
614
615  gdk_draw_rectangle (colorlist_pixmap, gc, FALSE, l, t, r-l, b-t);
616
617  gdk_gc_destroy(gc);
618}
619
620static gint colorlist_configure(GtkWidget *widget, GdkEventConfigure *event)
621{
622  if (colorlist_pixmap)
623    gdk_pixmap_unref(colorlist_pixmap);
624
625  colorlist_pixmap = gdk_pixmap_new(widget->window, widget->allocation.width,
626                    widget->allocation.height, -1);
627  colorlist_draw_pixmap(widget);
628
629  return TRUE;
630}
631
632// Redraw from the backing pixmap
633static gint colorlist_expose(GtkWidget *widget, GdkEventExpose *event)
634{
635  gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
636          colorlist_pixmap, event->area.x, event->area.y,
637          event->area.x, event->area.y,
638          event->area.width, event->area.height);
639
640  return FALSE;
641}
642
643static gint colorlist_key_press(GtkWidget* widget, GdkEventKey* event, gpointer data)
644{
645  int x;
646
647  switch (event->keyval)
648  {
649    case GDK_Up: x = cur_color - 14; break;
650    case GDK_Down: x = cur_color + 14; break;
651    case GDK_Left: x = cur_color - 1; break;
652    case GDK_Right: x = cur_color + 1; break;
653
654  default:
655    return TRUE;
656  }
657
658  if ((x > -1) && (x < 28))
659  {
660    cur_color = x;
661    colorlist_draw_pixmap(widget);
662    g_App->m_SelectedColor = x;
663    lcPostMessage(LC_MSG_COLOR_CHANGED, GINT_TO_POINTER(x));
664    gtk_widget_draw(widget, NULL);
665    preview->Redraw ();
666  }
667  gtk_signal_emit_stop_by_name (GTK_OBJECT(widget), "key_press_event");
668
669  return TRUE;
670}
671
672static gint colorlist_button_press(GtkWidget *widget, GdkEventButton *event)
673{
674  if (event->button == 1 && colorlist_pixmap != NULL)
675  {
676    int x = (int)(event->x * 14 / widget->allocation.width);
677    if (event->y > (widget->allocation.height/2))
678      x += 14;
679
680    if (x != cur_color)
681    {
682      cur_color = x;
683      colorlist_draw_pixmap(widget);
684      g_App->m_SelectedColor = x;
685      lcPostMessage(LC_MSG_COLOR_CHANGED, GINT_TO_POINTER(x));
686      gtk_widget_draw(widget, NULL);
687      preview->Redraw ();
688    }
689  }
690  gtk_window_set_focus(GTK_WINDOW(((GtkWidget*)(*main_window))), widget);
691
692  return TRUE;
693}
694
695void colorlist_set(int new_color)
696{
697  if (new_color != cur_color)
698  {
699    cur_color = new_color;
700    colorlist_draw_pixmap(colorlist);
701    gtk_widget_draw(colorlist, NULL);
702    preview->Redraw ();
703  }
704}
705
706// Create the pieces toolbar
707GtkWidget* create_piecebar (GtkWidget *window, GLWindow *share)
708{
709  GtkWidget *vbox1, *hbox, *vpan, *scroll_win, *frame, *button, *arrow;
710
711  frame = gtk_frame_new (NULL);
712  gtk_widget_show (frame);
713  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);               
714
715  vbox1 = gtk_vbox_new (FALSE, 0);
716  gtk_widget_show (vbox1);
717  gtk_container_add (GTK_CONTAINER (frame), vbox1);
718  gtk_container_border_width(GTK_CONTAINER (vbox1), 2);
719
720  vpan = gtk_vpaned_new ();
721  gtk_widget_show (vpan);
722  gtk_box_pack_start (GTK_BOX (vbox1), vpan, TRUE, TRUE, 0);
723
724  GtkWidget *w;
725  preview = new PiecePreview (share);
726  preview->Create (&w);
727  gtk_widget_set_usize (w, 100, 100);
728  gtk_widget_show (w);
729  gtk_container_add (GTK_CONTAINER (vpan), w);
730
731  scroll_win = gtk_scrolled_window_new (NULL, NULL);
732  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scroll_win),
733                  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
734  gtk_widget_show (scroll_win);
735  gtk_container_add (GTK_CONTAINER (vpan), scroll_win);
736
737  GtkTreeStore* store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
738  piecetree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
739  gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(piecetree), false);
740
741  GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
742  GtkTreeViewColumn* column;
743  column = gtk_tree_view_column_new_with_attributes("Piece", renderer, "text", 0, NULL);
744  gtk_tree_view_append_column(GTK_TREE_VIEW(piecetree), column);
745
746  GtkTreeSelection* select;
747  select = gtk_tree_view_get_selection(GTK_TREE_VIEW(piecetree));
748  gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
749  g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(piecetree_changed), NULL);
750
751  gtk_container_add(GTK_CONTAINER(scroll_win), piecetree);
752  gtk_widget_show(piecetree);
753
754  // Piece combo
755  hbox = gtk_hbox_new (FALSE, 1);
756  gtk_widget_show (hbox);
757  gtk_box_pack_start (GTK_BOX (vbox1), hbox, FALSE, TRUE, 1);
758
759  pieceentry = gtk_entry_new ();
760  gtk_widget_show (pieceentry);
761  gtk_box_pack_start(GTK_BOX(hbox), pieceentry, TRUE, TRUE, 0);
762  gtk_signal_connect(GTK_OBJECT(pieceentry), "changed", GTK_SIGNAL_FUNC(piececombo_changed), NULL);
763  gtk_signal_connect(GTK_OBJECT(pieceentry), "key_press_event", GTK_SIGNAL_FUNC(piececombo_key), NULL);
764
765  button = gtk_button_new();
766  gtk_widget_show (button);
767  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, TRUE, 0);
768  gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (piececombo_popup), NULL);
769
770  arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
771  gtk_widget_show (arrow);
772  gtk_container_add (GTK_CONTAINER (button), arrow);
773
774  // Color list
775  colorlist = gtk_drawing_area_new ();
776  gtk_widget_set_events (colorlist, GDK_EXPOSURE_MASK
777             | GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK);
778  GTK_WIDGET_SET_FLAGS(colorlist, GTK_CAN_FOCUS);
779  gtk_drawing_area_size(GTK_DRAWING_AREA(colorlist), 200, 30);
780  gtk_box_pack_start(GTK_BOX(vbox1), colorlist, FALSE, TRUE, 0);
781
782  gtk_signal_connect (GTK_OBJECT(colorlist), "expose_event",
783              (GtkSignalFunc) colorlist_expose, NULL);
784  gtk_signal_connect (GTK_OBJECT(colorlist),"configure_event",
785              (GtkSignalFunc) colorlist_configure, NULL);
786  gtk_signal_connect (GTK_OBJECT(colorlist), "button_press_event",
787              (GtkSignalFunc) colorlist_button_press, NULL);
788  gtk_signal_connect (GTK_OBJECT(colorlist), "key_press_event",
789              GTK_SIGNAL_FUNC(colorlist_key_press), NULL);
790
791  gtk_widget_show(colorlist);
792
793  fill_piecetree();
794
795  return frame;
796}
797
798// =============================================================================
799// Status bar
800
801GtkWidget *label_message, *label_position, *label_snap, *label_step;
802
803static void statusbar_listener (int message, void *data, void *user)
804{
805  if (message == LC_MSG_FOCUS_OBJECT_CHANGED)
806  {
807    char text[32];
808    Vector3 pos;
809
810    lcGetActiveProject()->GetFocusPosition(pos);
811    lcGetActiveProject()->ConvertToUserUnits(pos);
812
813    sprintf (text, "X: %.2f Y: %.2f Z: %.2f", pos[0], pos[1], pos[2]);
814    gtk_label_set (GTK_LABEL (label_position), text);
815  }
816}
817
818void create_statusbar(GtkWidget *window, GtkWidget *vbox)
819{
820  GtkWidget *hbox, *hbox1, *frame;
821
822  hbox = gtk_hbox_new (FALSE, 0);
823  gtk_widget_show (hbox);
824  gtk_widget_set_usize (hbox, -1, 24);
825  gtk_container_border_width (GTK_CONTAINER (hbox), 1);
826  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 2);
827
828  frame = gtk_frame_new (NULL);
829  gtk_widget_show (frame);
830  gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
831  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
832
833  hbox1 = gtk_hbox_new (FALSE, 0);
834  gtk_container_add (GTK_CONTAINER (frame), hbox1);
835  gtk_container_border_width (GTK_CONTAINER (hbox1), 0);
836  gtk_widget_show (hbox1);
837
838  label_message = gtk_label_new (" ");
839  gtk_widget_show (label_message);
840  gtk_box_pack_start (GTK_BOX (hbox1), label_message, FALSE, TRUE, 0);
841  gtk_label_set_justify (GTK_LABEL (label_message), GTK_JUSTIFY_LEFT);
842  gtk_misc_set_padding (GTK_MISC (label_message), 3, 0);
843
844  frame = gtk_frame_new (NULL);
845  gtk_widget_show (frame);
846  gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
847  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
848  gtk_widget_set_usize (frame, 150, -1);
849
850  hbox1 = gtk_hbox_new (FALSE, 0);
851  gtk_container_add (GTK_CONTAINER (frame), hbox1);
852  gtk_container_border_width (GTK_CONTAINER (hbox1), 0);
853  gtk_widget_show (hbox1);
854
855  label_position = gtk_label_new (" ");
856  gtk_widget_show (label_position);
857  gtk_box_pack_start (GTK_BOX (hbox1), label_position, TRUE, TRUE, 0);
858
859  frame = gtk_frame_new (NULL);
860  gtk_widget_show (frame);
861  gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
862  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
863  gtk_widget_set_usize (frame, 70, -1);
864
865  hbox1 = gtk_hbox_new (FALSE, 0);
866  gtk_container_add (GTK_CONTAINER (frame), hbox1);
867  gtk_container_border_width (GTK_CONTAINER (hbox1), 0);
868  gtk_widget_show (hbox1);
869
870  label_snap = gtk_label_new (" ");
871  gtk_widget_show (label_snap);
872  gtk_box_pack_start (GTK_BOX (hbox1), label_snap, TRUE, TRUE, 0);
873
874  frame = gtk_frame_new (NULL);
875  gtk_widget_show (frame);
876  gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, TRUE, 0);
877  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
878  gtk_widget_set_usize (frame, 70, -1);
879
880  hbox1 = gtk_hbox_new (FALSE, 0);
881  gtk_container_add (GTK_CONTAINER (frame), hbox1);
882  gtk_container_border_width (GTK_CONTAINER (hbox1), 0);
883  gtk_widget_show (hbox1);
884
885  label_step = gtk_label_new (" ");
886  gtk_widget_show (label_step);
887  gtk_box_pack_start (GTK_BOX (hbox1), label_step, TRUE, TRUE, 0);
888
889// FIXME: linux status bar listener
890//  messenger->Listen (&statusbar_listener, NULL);
891}
Note: See TracBrowser for help on using the browser.