/** * Returns a point describing the receiver's size. * * @return the receiver's size * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public Point getSize() { checkWidget(); if (image != null) { Rectangle rect = image.getBounds(); return new Point(rect.width, rect.height); } return new Point(width, height); }
/** * Returns a rectangle describing the receiver's size and location relative to its parent (or its * display if its parent is null). * * @return the receiver's bounding rectangle * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public Rectangle getBounds() { checkWidget(); if (image != null) { Rectangle rect = image.getBounds(); return new Rectangle(x, y, rect.width, rect.height); } return new Rectangle(x, y, width, height); }
/** * Sets the receiver's image at a column. * * @param index the column index * @param image the new image * @exception IllegalArgumentException * <ul> * <li>ERROR_INVALID_ARGUMENT - if the image has been disposed * </ul> * * @exception SWTException * <ul> * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver * </ul> */ public void setImage(int index, Image image) { checkWidget(); if (image != null && image.isDisposed()) { error(SWT.ERROR_INVALID_ARGUMENT); } if (image != null && image.type == SWT.ICON) { if (image.equals(_getImage(index))) return; } int count = Math.max(1, parent.getColumnCount()); if (0 > index || index > count - 1) return; int /*long*/ pixbuf = 0; if (image != null) { ImageList imageList = parent.imageList; if (imageList == null) imageList = parent.imageList = new ImageList(); int imageIndex = imageList.indexOf(image); if (imageIndex == -1) imageIndex = imageList.add(image); pixbuf = imageList.getPixbuf(imageIndex); } int modelIndex = parent.columnCount == 0 ? Table.FIRST_COLUMN : parent.columns[index].modelIndex; OS.gtk_list_store_set(parent.modelHandle, handle, modelIndex + Table.CELL_PIXBUF, pixbuf, -1); /* * Bug in GTK. When using fixed-height-mode, * row changes do not cause the row to be repainted. The fix is to * invalidate the row when it is cleared. */ if ((parent.style & SWT.VIRTUAL) != 0) { if (OS.GTK_VERSION >= OS.VERSION(2, 3, 2) && OS.GTK_VERSION < OS.VERSION(2, 6, 3)) { redraw(); } } /* * Bug in GTK. When in fixed height mode, GTK does not recalculate the cell renderer width * when the image is changed in the model. The fix is to force it to recalculate the width if * more space is required. */ if ((parent.style & SWT.VIRTUAL) != 0 && parent.currentItem == null) { if (OS.GTK_VERSION >= OS.VERSION(2, 3, 2)) { if (image != null) { int /*long*/ parentHandle = parent.handle; int /*long*/ column = OS.gtk_tree_view_get_column(parentHandle, index); int[] w = new int[1]; int /*long*/ pixbufRenderer = parent.getPixbufRenderer(column); OS.gtk_tree_view_column_cell_get_position(column, pixbufRenderer, null, w); if (w[0] < image.getBounds().width) { /* * There is no direct way to clear the cell renderer width so we * are relying on the fact that it is done as part of modifying * the style. */ int /*long*/ style = OS.gtk_widget_get_modifier_style(parentHandle); parent.modifyStyle(parentHandle, style); } } } } cached = true; }
void resize(int width, int height) { if (image != null) { Rectangle rect = image.getBounds(); width = rect.width; height = rect.height; } if (width == 0) width = 1; OS.FrameworkElement_Width(handle, width); OS.FrameworkElement_Height(handle, height); }
/** Compute the minimum size. */ private Point getTotalSize(Image image, String text) { Point size = new Point(0, 0); if (image != null) { Rectangle r = image.getBounds(); size.x += r.width; size.y += r.height; } GC gc = new GC(this); if (text != null && text.length() > 0) { Point e = gc.textExtent(text, DRAW_FLAGS); size.x += e.x; size.y = Math.max(size.y, e.y); if (image != null) size.x += GAP; } else { size.y = Math.max(size.y, gc.getFontMetrics().getHeight()); } gc.dispose(); return size; }
public static void main(String[] args) { final Display display = new Display(); final Image image = new Image(display, 16, 16); GC gc = new GC(image); gc.setBackground(display.getSystemColor(SWT.COLOR_RED)); gc.fillRectangle(image.getBounds()); gc.dispose(); final Shell shell = new Shell(display); shell.setText("Lazy Table"); shell.setLayout(new FillLayout()); final Table table = new Table(shell, SWT.BORDER | SWT.MULTI); table.setSize(200, 200); Thread thread = new Thread() { @Override public void run() { for (int i = 0; i < 20000; i++) { if (table.isDisposed()) return; final int[] index = new int[] {i}; display.syncExec( () -> { if (table.isDisposed()) return; TableItem item = new TableItem(table, SWT.NONE); item.setText("Table Item " + index[0]); item.setImage(image); }); } } }; thread.start(); shell.setSize(200, 200); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } image.dispose(); display.dispose(); }
int XmNexposureCallback(int w, int client_data, int call_data) { if ((style & SWT.SEPARATOR) != 0) return 0; int xDisplay = OS.XtDisplay(handle); if (xDisplay == 0) return 0; int xWindow = OS.XtWindow(handle); if (xWindow == 0) return 0; int[] argList = { OS.XmNcolormap, 0, OS.XmNwidth, 0, OS.XmNheight, 0, }; OS.XtGetValues(handle, argList, argList.length / 2); int width = argList[3], height = argList[5]; Image currentImage = image; boolean enabled = getEnabled(); if ((parent.style & SWT.FLAT) != 0) { boolean hasCursor = hasCursor(); /* Set the shadow thickness */ int thickness = 0; if (set || (hasCursor && enabled)) { thickness = Math.min(2, display.buttonShadowThickness); } argList = new int[] {OS.XmNshadowThickness, thickness}; OS.XtSetValues(handle, argList, argList.length / 2); /* Determine if hot image should be used */ if (enabled && hasCursor && hotImage != null) { currentImage = hotImage; } } GCData data = new GCData(); data.device = display; data.display = xDisplay; data.drawable = xWindow; data.font = parent.font; data.colormap = argList[1]; int xGC = OS.XCreateGC(xDisplay, xWindow, 0, null); if (xGC == 0) SWT.error(SWT.ERROR_NO_HANDLES); GC gc = GC.motif_new(xGC, data); XmAnyCallbackStruct cb = new XmAnyCallbackStruct(); OS.memmove(cb, call_data, XmAnyCallbackStruct.sizeof); if (cb.event != 0) { XExposeEvent xEvent = new XExposeEvent(); OS.memmove(xEvent, cb.event, XExposeEvent.sizeof); Rectangle rect = new Rectangle(xEvent.x, xEvent.y, xEvent.width, xEvent.height); gc.setClipping(rect); } if (!enabled) { currentImage = disabledImage; if (currentImage == null && image != null) { currentImage = new Image(display, image, SWT.IMAGE_DISABLE); } Color disabledColor = display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); gc.setForeground(disabledColor); } else { gc.setForeground(parent.getForeground()); } gc.setBackground(parent.getBackground()); int textX = 0, textY = 0, textWidth = 0, textHeight = 0; if (text.length() != 0) { int flags = SWT.DRAW_DELIMITER | SWT.DRAW_TAB | SWT.DRAW_MNEMONIC; Point textExtent = gc.textExtent(text, flags); textWidth = textExtent.x; textHeight = textExtent.y; } int imageX = 0, imageY = 0, imageWidth = 0, imageHeight = 0; if (currentImage != null) { Rectangle imageBounds = currentImage.getBounds(); imageWidth = imageBounds.width; imageHeight = imageBounds.height; } int spacing = 0; if (textWidth != 0 && imageWidth != 0) spacing = 2; if ((parent.style & SWT.RIGHT) != 0) { imageX = (width - imageWidth - textWidth - spacing) / 2; imageY = (height - imageHeight) / 2; textX = spacing + imageX + imageWidth; textY = (height - textHeight) / 2; } else { imageX = (width - imageWidth) / 2; imageY = (height - imageHeight - textHeight - spacing) / 2; textX = (width - textWidth) / 2; textY = spacing + imageY + imageHeight; } if ((style & SWT.DROP_DOWN) != 0) { textX -= 6; imageX -= 6; } if (textWidth > 0) { int flags = SWT.DRAW_DELIMITER | SWT.DRAW_TAB | SWT.DRAW_MNEMONIC | SWT.DRAW_TRANSPARENT; gc.drawText(text, textX, textY, flags); } if (imageWidth > 0) gc.drawImage(currentImage, imageX, imageY); if ((style & SWT.DROP_DOWN) != 0) { int startX = width - 12, startY = (height - 2) / 2; int[] arrow = {startX, startY, startX + 3, startY + 3, startX + 6, startY}; gc.setBackground(parent.getForeground()); gc.fillPolygon(arrow); gc.drawPolygon(arrow); } gc.dispose(); OS.XFreeGC(xDisplay, xGC); if (!enabled && disabledImage == null) { if (currentImage != null) currentImage.dispose(); } return 0; }
void paint(Event event) { if (row == null) return; int columnIndex = column == null ? 0 : table.indexOf(column); GC gc = event.gc; gc.setBackground(getBackground()); gc.setForeground(getForeground()); gc.fillRectangle(event.x, event.y, event.width, event.height); int x = 0; Point size = getSize(); Image image = row.getImage(columnIndex); if (image != null) { Rectangle imageSize = image.getBounds(); int imageY = (size.y - imageSize.height) / 2; gc.drawImage(image, x, imageY); x += imageSize.width; } String text = row.getText(columnIndex); if (text.length() > 0) { Rectangle bounds = row.getBounds(columnIndex); Point extent = gc.stringExtent(text); // Temporary code - need a better way to determine table trim String platform = SWT.getPlatform(); if ("win32".equals(platform)) { // $NON-NLS-1$ if (table.getColumnCount() == 0 || columnIndex == 0) { x += 2; } else { int alignmnent = column.getAlignment(); switch (alignmnent) { case SWT.LEFT: x += 6; break; case SWT.RIGHT: x = bounds.width - extent.x - 6; break; case SWT.CENTER: x += (bounds.width - x - extent.x) / 2; break; } } } else { if (table.getColumnCount() == 0) { x += 5; } else { int alignmnent = column.getAlignment(); switch (alignmnent) { case SWT.LEFT: x += 5; break; case SWT.RIGHT: x = bounds.width - extent.x - 2; break; case SWT.CENTER: x += (bounds.width - x - extent.x) / 2 + 2; break; } } } int textY = (size.y - extent.y) / 2; gc.drawString(text, x, textY); } if (isFocusControl()) { Display display = getDisplay(); gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE)); gc.drawFocus(0, 0, size.x, size.y); } }
private void drag(Event dragEvent) { DNDEvent event = new DNDEvent(); event.widget = this; event.x = dragEvent.x; event.y = dragEvent.y; event.time = OS.GetMessageTime(); event.doit = true; notifyListeners(DND.DragStart, event); if (!event.doit || transferAgents == null || transferAgents.length == 0) return; int[] pdwEffect = new int[1]; int operations = opToOs(getStyle()); Display display = control.getDisplay(); String key = "org.eclipse.swt.internal.win32.runMessagesInIdle"; // $NON-NLS-1$ Object oldValue = display.getData(key); display.setData(key, Boolean.TRUE); ImageList imagelist = null; Image image = event.image; hwndDrag = 0; topControl = null; if (image != null) { imagelist = new ImageList(SWT.NONE); imagelist.add(image); topControl = control.getShell(); /* * Bug in Windows. The image is inverted if the shell is RIGHT_TO_LEFT. * The fix is to create a transparent window that covers the shell client * area and use it during the drag to prevent the image from being inverted. * On XP if the shell is RTL, the image is not displayed. */ int offsetX = event.offsetX; hwndDrag = topControl.handle; if ((topControl.getStyle() & SWT.RIGHT_TO_LEFT) != 0) { offsetX = image.getBounds().width - offsetX; RECT rect = new RECT(); OS.GetClientRect(topControl.handle, rect); hwndDrag = OS.CreateWindowEx( OS.WS_EX_TRANSPARENT | OS.WS_EX_NOINHERITLAYOUT, WindowClass, null, OS.WS_CHILD | OS.WS_CLIPSIBLINGS, 0, 0, rect.right - rect.left, rect.bottom - rect.top, topControl.handle, 0, OS.GetModuleHandle(null), null); OS.ShowWindow(hwndDrag, OS.SW_SHOW); } OS.ImageList_BeginDrag(imagelist.getHandle(), 0, offsetX, event.offsetY); /* * Feature in Windows. When ImageList_DragEnter() is called, * it takes a snapshot of the screen If a drag is started * when another window is in front, then the snapshot will * contain part of the other window, causing pixel corruption. * The fix is to force all paints to be delivered before * calling ImageList_DragEnter(). */ if (OS.IsWinCE) { OS.UpdateWindow(topControl.handle); } else { int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; OS.RedrawWindow(topControl.handle, null, 0, flags); } POINT pt = new POINT(); pt.x = dragEvent.x; pt.y = dragEvent.y; OS.MapWindowPoints(control.handle, 0, pt, 1); RECT rect = new RECT(); OS.GetWindowRect(hwndDrag, rect); OS.ImageList_DragEnter(hwndDrag, pt.x - rect.left, pt.y - rect.top); } int result = COM.DRAGDROP_S_CANCEL; try { result = COM.DoDragDrop(iDataObject.getAddress(), iDropSource.getAddress(), operations, pdwEffect); } finally { // ensure that we don't leave transparent window around if (hwndDrag != 0) { OS.ImageList_DragLeave(hwndDrag); OS.ImageList_EndDrag(); imagelist.dispose(); if (hwndDrag != topControl.handle) OS.DestroyWindow(hwndDrag); hwndDrag = 0; topControl = null; } display.setData(key, oldValue); } int operation = osToOp(pdwEffect[0]); if (dataEffect == DND.DROP_MOVE) { operation = (operation == DND.DROP_NONE || operation == DND.DROP_COPY) ? DND.DROP_TARGET_MOVE : DND.DROP_MOVE; } else { if (dataEffect != DND.DROP_NONE) { operation = dataEffect; } } event = new DNDEvent(); event.widget = this; event.time = OS.GetMessageTime(); event.doit = (result == COM.DRAGDROP_S_DROP); event.detail = operation; notifyListeners(DND.DragEnd, event); dataEffect = DND.DROP_NONE; }
void onPaint(PaintEvent event) { Rectangle rect = getClientArea(); if (rect.width == 0 || rect.height == 0) return; boolean shortenText = false; String t = text; Image img = image; int availableWidth = Math.max(0, rect.width - (leftMargin + rightMargin)); Point extent = getTotalSize(img, t); if (extent.x > availableWidth) { img = null; extent = getTotalSize(img, t); if (extent.x > availableWidth) { shortenText = true; } } GC gc = event.gc; String[] lines = text == null ? null : splitString(text); // shorten the text if (shortenText) { extent.x = 0; for (int i = 0; i < lines.length; i++) { Point e = gc.textExtent(lines[i], DRAW_FLAGS); if (e.x > availableWidth) { lines[i] = shortenText(gc, lines[i], availableWidth); extent.x = Math.max(extent.x, getTotalSize(null, lines[i]).x); } else { extent.x = Math.max(extent.x, e.x); } } if (appToolTipText == null) { super.setToolTipText(text); } } else { super.setToolTipText(appToolTipText); } // determine horizontal position int x = rect.x + leftMargin; if (align == SWT.CENTER) { x = (rect.width - extent.x) / 2; } if (align == SWT.RIGHT) { x = rect.width - rightMargin - extent.x; } // draw a background image behind the text try { if (backgroundImage != null) { // draw a background image behind the text Rectangle imageRect = backgroundImage.getBounds(); // tile image to fill space gc.setBackground(getBackground()); gc.fillRectangle(rect); int xPos = 0; while (xPos < rect.width) { int yPos = 0; while (yPos < rect.height) { gc.drawImage(backgroundImage, xPos, yPos); yPos += imageRect.height; } xPos += imageRect.width; } } else if (gradientColors != null) { // draw a gradient behind the text final Color oldBackground = gc.getBackground(); if (gradientColors.length == 1) { if (gradientColors[0] != null) gc.setBackground(gradientColors[0]); gc.fillRectangle(0, 0, rect.width, rect.height); } else { final Color oldForeground = gc.getForeground(); Color lastColor = gradientColors[0]; if (lastColor == null) lastColor = oldBackground; int pos = 0; for (int i = 0; i < gradientPercents.length; ++i) { gc.setForeground(lastColor); lastColor = gradientColors[i + 1]; if (lastColor == null) lastColor = oldBackground; gc.setBackground(lastColor); if (gradientVertical) { final int gradientHeight = (gradientPercents[i] * rect.height / 100) - pos; gc.fillGradientRectangle(0, pos, rect.width, gradientHeight, true); pos += gradientHeight; } else { final int gradientWidth = (gradientPercents[i] * rect.width / 100) - pos; gc.fillGradientRectangle(pos, 0, gradientWidth, rect.height, false); pos += gradientWidth; } } if (gradientVertical && pos < rect.height) { gc.setBackground(getBackground()); gc.fillRectangle(0, pos, rect.width, rect.height - pos); } if (!gradientVertical && pos < rect.width) { gc.setBackground(getBackground()); gc.fillRectangle(pos, 0, rect.width - pos, rect.height); } gc.setForeground(oldForeground); } gc.setBackground(oldBackground); } else { if (background != null || (getStyle() & SWT.DOUBLE_BUFFERED) == 0) { gc.setBackground(getBackground()); gc.fillRectangle(rect); } } } catch (SWTException e) { if ((getStyle() & SWT.DOUBLE_BUFFERED) == 0) { gc.setBackground(getBackground()); gc.fillRectangle(rect); } } // draw border int style = getStyle(); if ((style & SWT.SHADOW_IN) != 0 || (style & SWT.SHADOW_OUT) != 0) { paintBorder(gc, rect); } /* * Compute text height and image height. If image height is more than * the text height, draw image starting from top margin. Else draw text * starting from top margin. */ Rectangle imageRect = null; int lineHeight = 0, textHeight = 0, imageHeight = 0; if (img != null) { imageRect = img.getBounds(); imageHeight = imageRect.height; } if (lines != null) { lineHeight = gc.getFontMetrics().getHeight(); textHeight = lines.length * lineHeight; } int imageY = 0, midPoint = 0, lineY = 0; if (imageHeight > textHeight) { if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) imageY = rect.y + (rect.height - imageHeight) / 2; else imageY = topMargin; midPoint = imageY + imageHeight / 2; lineY = midPoint - textHeight / 2; } else { if (topMargin == DEFAULT_MARGIN && bottomMargin == DEFAULT_MARGIN) lineY = rect.y + (rect.height - textHeight) / 2; else lineY = topMargin; midPoint = lineY + textHeight / 2; imageY = midPoint - imageHeight / 2; } // draw the image if (img != null) { gc.drawImage( img, 0, 0, imageRect.width, imageHeight, x, imageY, imageRect.width, imageHeight); x += imageRect.width + GAP; extent.x -= imageRect.width + GAP; } // draw the text if (lines != null) { gc.setForeground(getForeground()); for (int i = 0; i < lines.length; i++) { int lineX = x; if (lines.length > 1) { if (align == SWT.CENTER) { int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x; lineX = x + Math.max(0, (extent.x - lineWidth) / 2); } if (align == SWT.RIGHT) { int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x; lineX = Math.max(x, rect.x + rect.width - rightMargin - lineWidth); } } gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS); lineY += lineHeight; } } }