drag+drop group highlight changes, fileref tweaks + warn, tweak awdw for ref/edl...
[goodguy/cinelerra.git] / cinelerra-5.1 / guicast / bcwindowbase.C
index 0d9f95d4eede1a54100c45376e4b53a00fae282f..e861238e388e177a041b093407513421cb1ea8c9 100644 (file)
@@ -624,7 +624,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title
                }
 
                if(!hidden) show_window();
-
+               init_glyphs();
        }
 
        draw_background(0, 0, this->w, this->h);
@@ -1261,35 +1261,8 @@ if( debug && event->type != ClientMessage ) {
                case XK_F10:            key_pressed = KEY_F10;  break;
                case XK_F11:            key_pressed = KEY_F11;  break;
                case XK_F12:            key_pressed = KEY_F12;  break;
-
+// activates remote
                case XK_Menu:           key_pressed = KPMENU;   break;  /* menu */
-// remote control
-// above       case XK_KP_Enter:       key_pressed = KPENTER;  break;  /* check */
-               case XF86XK_MenuKB:     key_pressed = KPMENU;   break;  /* menu */
-// intercepted case XF86XK_PowerDown: key_pressed = KPPOWER;   break;  /* Power */
-               case XF86XK_Launch1:    key_pressed = KPTV;     break;  /* TV */
-               case XF86XK_Launch2:    key_pressed = KPDVD;    break;  /* DVD */
-// intercepted case XF86XK_WWW:        key_pressed = KPWWEB;   break;  /* WEB */
-               case XF86XK_Launch3:    key_pressed = KPBOOK;   break;  /* book */
-               case XF86XK_Launch4:    key_pressed = KPHAND;   break;  /* hand */
-               case XF86XK_Reply:      key_pressed = KPTMR;    break;  /* timer */
-               case SunXK_Front:       key_pressed = KPMAXW;   break;  /* max */
-// above       case XK_Left:           key_pressed = LEFT;     break;  /* left */
-// above       case XK_Right:          key_pressed = RIGHT;    break;  /* right */
-// above       case XK_Down:           key_pressed = DOWN;     break;  /* down */
-// above       case XK_Up:             key_pressed = UP;       break;  /* up */
-// above       case XK_SPACE:          key_pressed = KPSPACE;  break;  /* ok */
-// intercepted case XF86XK_AudioRaiseVolume: key_pressed = KPVOLU;     break;  /* VOL + */
-// intercepted case XF86XK_AudioMute: key_pressed = KPMUTE;    break;  /* MUTE */
-// intercepted case XF86XK_AudioLowerVolume: key_pressed = KPVOLD;     break;  /* VOL - */
-               case XF86XK_ScrollUp:   key_pressed = KPCHUP;   break;  /* CH + */
-               case XF86XK_ScrollDown: key_pressed = KPCHDN;   break;  /* CH - */
-               case XF86XK_AudioRecord: key_pressed = KPRECD;  break;  /* ( o) red */
-               case XF86XK_Forward:    key_pressed = KPPLAY;   break;  /* ( >) */
-               case XK_Redo:           key_pressed = KPFWRD;   break;  /* (>>) */
-               case XF86XK_Back:       key_pressed = KPBACK;   break;  /* (<<) */
-               case XK_Cancel:         key_pressed = KPSTOP;   break;  /* ([]) */
-               case XK_Pause:          key_pressed = KPAUSE;   break;  /* ('') */
 
                default:
                        key_pressed = keysym & 0xff;
@@ -2427,6 +2400,33 @@ xft_init_lock.unlock();
 #endif // HAVE_XFT
 }
 
+void BC_WindowBase::init_glyphs()
+{
+// draw all ascii char glyphs
+//  There are problems with some/my graphics boards/drivers
+//  which cause some glyphs to be munged if draws occur while
+//  the font is being loaded.  This code fills the font caches
+//  by drawing all the ascii glyphs before the system starts.
+//  Not a fix, but much better than nothing.
+       static int inited = 0;
+       if( inited ) return;
+       XGrabServer(display);
+       XSync(display, 0);
+       inited = 1;
+       int cur_font = current_font;
+// locale encodings, needed glyphs to be preloaded
+       const char *text = _( // ascii 0x20...0x7e
+               " !\"#$%&'()*+,-./0123456789:;<=>?"
+               "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
+               "`abcdefghijklmnopqrstuvwxyz{|}~");
+       for( int font=SMALLFONT; font<=LARGEFONT; ++font ) {
+               set_font(font);
+               draw_text(5,5, text, 0);
+       }
+       set_font(cur_font);
+       XUngrabServer(display);
+}
+
 void BC_WindowBase::init_im()
 {
        XIMStyles *xim_styles;
@@ -3036,6 +3036,39 @@ int BC_WindowBase::get_text_height(int font, const char *text)
        return h * rowh;
 }
 
+// truncate the text with ... & return a new string
+char *BC_WindowBase::get_truncated_text(int font, const char *text, int max_w)
+{
+       char *result = cstrdup(text);
+       int text_w = get_text_width(font, text);
+       int ci = -1, len = strlen(text);
+       if( text_w > max_w ) {
+// get center of string
+               int cx = text_w/2, best = INT_MAX;
+               for( int i=1; i<=len; ++i ) {
+                       int cw = get_text_width(font, text, i);
+                       if( abs(cw-cx) < abs(best-cx) ) {
+                               best = cw;  ci = i;
+                       }
+               }
+       }
+       if( ci > 0 && ci < len-1 ) {
+// insert ... in the center
+               result[ci-1] = result[ci] = result[ci+1] = '.';
+
+               while( ci-2>=0 && ci+2<(int)strlen(result) &&
+                      get_text_width(font, result) > max_w ) {
+// take away a character from the longer side
+                       int left_w = get_text_width(font, result, ci-2);
+                       int right_w = get_text_width(font, result + ci+3);
+                       int i = left_w > right_w ? --ci-1 : ci+2;
+                       while( (result[i]=result[i+1])!=0 ) ++i;
+               }
+       }
+
+       return result;
+}
+
 BC_Bitmap* BC_WindowBase::new_bitmap(int w, int h, int color_model)
 {
        if(color_model < 0) color_model = top_level->get_color_model();
@@ -4181,6 +4214,8 @@ void BC_WindowBase::set_force_tooltip(int v)
 
 int BC_WindowBase::raise_window(int do_flush)
 {
+       if( hidden ) return 1;
+       if( wait_viewable(500) ) return 1;
        XRaiseWindow(top_level->display, win);
        if(do_flush) XFlush(top_level->display);
        return 0;
@@ -4237,6 +4272,26 @@ void BC_WindowBase::set_title(const char *text, int utf8)
        flush();
 }
 
+// must be RGBA8888
+void BC_WindowBase::set_net_icon(VFrame *data)
+{
+       int width = data->get_w(), height = data->get_h();
+       int size = 2 + width * height;
+       unsigned long *icon_data = new unsigned long[size];
+       unsigned long *lp = icon_data;
+       *lp++ = width;  *lp++ = height;
+       uint8_t **rows = data->get_rows();
+       for( int y=0; y<height; ++y ) {
+               unsigned *up = (unsigned *)rows[y];
+               for( int x=0; x<width; ++x )
+                       *lp++ = *(unsigned *)up++;
+       }
+       Atom NetWMIcon = XInternAtom(display, "_NET_WM_ICON", True);
+       XChangeProperty(top_level->display, top_level->win, NetWMIcon,
+                XA_CARDINAL, 32, PropModeReplace, (unsigned char *)icon_data, size);
+       delete [] icon_data;
+}
+
 const char *BC_WindowBase::get_title()
 {
        return title;
@@ -4258,27 +4313,28 @@ int BC_WindowBase::set_icon(VFrame *data)
        icon_pixmap = new BC_Pixmap(top_level, data, PIXMAP_ALPHA, 1);
 
        if(icon_window) delete icon_window;
-       icon_window = new BC_Popup(this,
-               (int)BC_INFINITY,
-               (int)BC_INFINITY,
-               icon_pixmap->get_w(),
-               icon_pixmap->get_h(),
-               -1,
-               1, // All windows are hidden initially
+       icon_window = new BC_Popup(this, 0, 0,
+               icon_pixmap->get_w(), icon_pixmap->get_h(),
+               -1, 1, // All windows are hidden initially
                icon_pixmap);
 
-       XWMHints wm_hints;
-       wm_hints.flags = WindowGroupHint | IconPixmapHint | IconMaskHint | IconWindowHint;
+       XWMHints wm_hints;  memset(&wm_hints, 0, sizeof(wm_hints));
+       wm_hints.flags = IconPixmapHint; // | IconMaskHint | IconWindowHint;
        wm_hints.icon_pixmap = icon_pixmap->get_pixmap();
        wm_hints.icon_mask = icon_pixmap->get_alpha();
        wm_hints.icon_window = icon_window->win;
-       wm_hints.window_group = XGroupLeader;
+       if( XGroupLeader ) {
+               wm_hints.flags |= WindowGroupHint;
+               wm_hints.window_group = XGroupLeader;
+       }
 
 // for(int i = 0; i < 1000; i++)
 // printf("02x ", icon_pixmap->get_alpha()->get_row_pointers()[0][i]);
 // printf("\n");
 
        XSetWMHints(top_level->display, top_level->win, &wm_hints);
+
+       set_net_icon(data);
        XSync(top_level->display, 0);
        return 0;
 }
@@ -4576,3 +4632,15 @@ void BC_WindowBase::focus()
                XSetInputFocus(top_level->display, top_level->win, RevertToParent, CurrentTime);
 }
 
+int BC_WindowBase::wait_viewable(int ms)
+{
+       Timer timer;
+       XWindowAttributes xwa;
+       do {
+               XGetWindowAttributes(top_level->display, top_level->win, &xwa);
+               if( xwa.map_state == IsViewable ) return 1;
+               usleep(10000);
+       } while( timer.get_difference() < ms );
+       return 0;
+}
+