home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / ProxyIcon.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  6.2 KB  |  254 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.    ProxyIcon.cpp -- a label that you can drag from.
  20.    Created: Chris Toshok <toshok@netscape.com>, 1-Dec-96.
  21.    */
  22.  
  23.  
  24.  
  25. #include "ProxyIcon.h"
  26. #include <Xm/Label.h>
  27.  
  28. #define NONMOTIF_DND
  29.  
  30. #ifdef DEBUG_toshok
  31. #define D(x) x
  32. #else
  33. #define D(x)
  34. #endif
  35.  
  36. #if defined(USE_MOTIF_DND)
  37. fe_dnd_Source _xfe_dragsource = { 0 };
  38. #else
  39. extern fe_dnd_Source _xfe_dragsource;
  40. #endif /* USE_MOTIF_DND */
  41.  
  42. XFE_ProxyIcon::XFE_ProxyIcon(XFE_Component *toplevel_component,
  43.                  Widget parent, char *name, fe_icon *icon)
  44.   : XFE_Component(toplevel_component)
  45. {
  46.   Widget label;
  47.   m_icon = icon;
  48.  
  49.   m_toplevel = toplevel_component;
  50.  
  51.   label = XmCreateLabel(parent, name, NULL, 0);
  52.  
  53.   setBaseWidget(label);
  54.  
  55.   XtInsertEventHandler(label, ButtonPressMask | ButtonReleaseMask
  56.                | PointerMotionMask, False,
  57.                buttonEventHandler, this, XtListHead);
  58.  
  59.   m_activity = 0;
  60.   m_lastmotionx = 
  61.       m_lastmotiony = 0;
  62.   m_dragtype = FE_DND_NONE;
  63.  
  64.   setIcon(icon);
  65. }
  66.  
  67. void
  68. XFE_ProxyIcon::setIcon(fe_icon *icon)
  69. {
  70.   m_icon = icon;
  71.  
  72.   if (m_icon && m_icon->pixmap)
  73.     {
  74.       XtVaSetValues(m_widget,
  75.             XmNlabelType, XmPIXMAP,
  76.             XmNlabelPixmap, icon->pixmap,
  77.             NULL);
  78.     }
  79. }
  80.  
  81. fe_icon *
  82. XFE_ProxyIcon::getIcon()
  83. {
  84.   return m_icon;
  85. }
  86.  
  87. void
  88. XFE_ProxyIcon::setDragType(fe_dnd_Type dragtype, XFE_Component *drag_source,
  89.                fe_dnd_SourceDropFunc sourcedropfunc)
  90. {
  91.   m_dragtype = dragtype;
  92.   m_source = drag_source;
  93.   m_sourcedropfunc = sourcedropfunc;
  94. }
  95.  
  96. void
  97. XFE_ProxyIcon::makeDragWidget(int x, int y)
  98. {
  99.   Visual *v = 0;
  100.   Colormap cmap = 0;
  101.   Cardinal depth = 0;
  102.   Widget label;
  103.   //  fe_icon *icon;
  104.   Widget shell;
  105.   Pixmap dragPixmap;
  106.  
  107.   D(printf("hot (x,y) = (%d,%d)\n", x, y);)
  108.  
  109.   if (_xfe_dragsource.widget) return;  
  110.  
  111.   shell = m_toplevel->getBaseWidget();
  112.  
  113.   XtVaGetValues (shell, XtNvisual, &v, XtNcolormap, &cmap,
  114.          XtNdepth, &depth, 0);
  115.  
  116.   _xfe_dragsource.type = m_dragtype; // XXX column drags happen when the row was a header.
  117.   _xfe_dragsource.hotx = x;
  118.   _xfe_dragsource.hoty = y;
  119.   _xfe_dragsource.closure = m_dragtype == FE_DND_COLUMN ? (void*)this : (void*)m_source;
  120.   _xfe_dragsource.func = m_sourcedropfunc;
  121.  
  122.   XP_ASSERT(m_icon != NULL);
  123.   if (m_icon == NULL) return;
  124.  
  125.   dragPixmap = m_icon->pixmap;
  126.  
  127.   _xfe_dragsource.widget = XtVaCreateWidget("drag_win",
  128.                        overrideShellWidgetClass,
  129.                        m_widget,
  130.                        XmNwidth, m_icon->width,
  131.                        XmNheight, m_icon->height,
  132.                        XmNvisual, v,
  133.                        XmNcolormap, cmap,
  134.                        XmNdepth, depth,
  135.                        XmNborderWidth, 0,
  136.                        NULL);
  137.   
  138.   label = XtVaCreateManagedWidget ("label",
  139.                    xmLabelWidgetClass,
  140.                    _xfe_dragsource.widget,
  141.                    XmNlabelType, XmPIXMAP,
  142.                    XmNlabelPixmap, dragPixmap,
  143.                    NULL);
  144. }
  145.  
  146. void
  147. XFE_ProxyIcon::destroyDragWidget()
  148. {
  149.   if (!_xfe_dragsource.widget) return;
  150.   XtDestroyWidget (_xfe_dragsource.widget);
  151.   _xfe_dragsource.widget = NULL;
  152. }
  153.  
  154. void
  155. XFE_ProxyIcon::buttonEvent(XEvent *event, Boolean *c)
  156. {
  157.   int x = event->xbutton.x;
  158.   int y = event->xbutton.y;
  159.  
  160.   m_ignoreevents = False;
  161.  
  162.   switch (event->type)
  163.     {
  164.     case ButtonPress:
  165.       D(printf ("ButtonPress\n");)
  166.       /* Always ignore btn3. Btn3 is for popups. - dp */
  167.       if (event->xbutton.button == 3) break;
  168.  
  169.       m_activity |= ButtonPressMask;
  170.       m_ignoreevents = True;
  171.  
  172.       m_lastmotionx = x;
  173.       m_lastmotiony = y;
  174.  
  175.       // Save this position off so we can draw the widget
  176.       // with the appropriate hot spot.  Ie, you should drag
  177.       // the icon from the point where you clicked on it, not
  178.       // some predetermined hot spot..
  179.       m_hotSpot_x = x;
  180.       m_hotSpot_y = y;
  181.       break;
  182.     case ButtonRelease:
  183.       if (m_activity & ButtonPressMask)
  184.     {
  185.       if (m_activity & PointerMotionMask)
  186.         {
  187.           /* handle the drop */
  188.           fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_DROP);
  189.           fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_END);
  190.  
  191.           destroyDragWidget();
  192.         }
  193.     }
  194.  
  195.       m_activity = 0;
  196.       
  197.       break;
  198. #ifdef NONMOTIF_DND
  199.     case MotionNotify:
  200.       if (m_dragtype == FE_DND_NONE)
  201.     break;
  202.  
  203.       if (!(m_activity & PointerMotionMask) &&
  204.       (abs(x - m_lastmotionx) < 5 && abs(y - m_lastmotiony) < 5)) 
  205.     {
  206.       /* We aren't yet dragging, and the mouse hasn't moved enough for
  207.          this to be considered a drag. */
  208.       break;
  209.     }
  210.  
  211.       if (m_activity & ButtonPressMask) 
  212.     {
  213.       /* ok, the pointer moved while a button was held.
  214.        * we're gonna drag some stuff.
  215.        */
  216.       m_ignoreevents = True;
  217.  
  218.       if (!(m_activity & PointerMotionMask)) 
  219.         {
  220.           // Create a drag source.
  221.           // We want the mouse-down location, not the last one. 
  222.           makeDragWidget(m_hotSpot_x, m_hotSpot_y);
  223.           fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_START);
  224.  
  225.           m_activity |= PointerMotionMask;
  226.         }
  227.       
  228.       fe_dnd_DoDrag(&_xfe_dragsource, event, FE_DND_DRAG);
  229.       
  230.       /* Now, force all the additional mouse motion events that are
  231.          lingering around on the server to come to us, so that Xt can
  232.          compress them away.  Yes, XSync really does improve performance
  233.          in this case, not hurt it. */
  234.       XSync(XtDisplay(m_widget), False);
  235.     }
  236.       
  237.       m_lastmotionx = x;
  238.       m_lastmotiony = y;
  239.       break;
  240. #endif
  241.     }
  242.   
  243.   if (m_ignoreevents) 
  244.     *c = False;
  245. }
  246.  
  247. void 
  248. XFE_ProxyIcon::buttonEventHandler(Widget, XtPointer clientData, XEvent *event, Boolean *cont)
  249. {
  250.   XFE_ProxyIcon *obj = (XFE_ProxyIcon*)clientData;
  251.  
  252.   obj->buttonEvent(event, cont);
  253. }
  254.