Petri Hintukainen pushed to branch master at VideoLAN / libbluray


Commits:
afda5095 by spotter at 2026-01-30T15:16:42+00:00
BD-J: Implement HTextLook for HStaticText/HText/HTextButton

- - - - -


2 changed files:

- src/libbluray/bdj/java/org/havi/ui/HDefaultTextLayoutManager.java
- src/libbluray/bdj/java/org/havi/ui/HTextLook.java


Changes:

=====================================
src/libbluray/bdj/java/org/havi/ui/HDefaultTextLayoutManager.java
=====================================
@@ -38,17 +38,17 @@ public class HDefaultTextLayoutManager implements 
HTextLayoutManager {
     {
         Dimension size = new Dimension(0, 0);
 
+        Font font = hvisible.getFont();
+        FontMetrics fontMetrics = hvisible.getFontMetrics(font);
+        if (fontMetrics == null) {
+            return new Dimension(0, 0);
+        }
+
         for (int state = HVisible.FIRST_STATE; state <= HVisible.LAST_STATE; 
state++) {
             String text = hvisible.getTextContent(state);
             if (text != null && !text.equals("")) {
                 String[] lines = StrUtil.split(text, '\n');
 
-                Graphics g = hvisible.getGraphics();
-                if (g == null)
-                    continue;
-                FontMetrics fontMetrics = g.getFontMetrics(hvisible.getFont());
-                g.dispose();
-
                 int lineHeight = fontMetrics.getHeight();
                 int textHeight = lines.length * lineHeight;
                 if (textHeight > size.height) {
@@ -63,6 +63,7 @@ public class HDefaultTextLayoutManager implements 
HTextLayoutManager {
                 }
             }
         }
+
         return size;
     }
 
@@ -83,9 +84,9 @@ public class HDefaultTextLayoutManager implements 
HTextLayoutManager {
 
         String[] lines = StrUtil.split(markedUpString, '\n');
 
-        Font font = v.getFont();
-        g.setFont(font);
+        g.setFont(v.getFont());
         FontMetrics fontMetrics = g.getFontMetrics();
+        g.setColor(v.getForeground());
 
         int ascent = fontMetrics.getAscent();
         int descent = Math.abs(fontMetrics.getDescent());


=====================================
src/libbluray/bdj/java/org/havi/ui/HTextLook.java
=====================================
@@ -2,6 +2,7 @@
  * This file is part of libbluray
  * Copyright (C) 2010  William Hahne
  * Copyright (C) 2013  Petri Hintukainen <[email protected]>
+ * Copyright (C) 2026  libbluray project
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,47 +22,79 @@
 package org.havi.ui;
 
 import java.awt.Color;
-import java.awt.Graphics;
 import java.awt.Dimension;
+import java.awt.Graphics;
 import java.awt.Insets;
 
-import org.videolan.Logger;
-
 public class HTextLook implements HExtendedLook {
 
+    private static final Insets DEFAULT_INSETS = new Insets(2, 2, 2, 2);
+    private static final Insets NO_INSETS = new Insets(0, 0, 0, 0);
+
     public HTextLook() {
     }
 
     public void fillBackground(Graphics g, HVisible visible, int state) {
         if (visible.getBackgroundMode() == HVisible.BACKGROUND_FILL) {
             Color color = visible.getBackground();
-            Dimension dimension = visible.getSize();
-            g.setColor(color);
-            g.fillRect(0, 0, dimension.width, dimension.height);
+            if (color != null) {
+                Dimension dimension = visible.getSize();
+                g.setColor(color);
+                g.fillRect(0, 0, dimension.width, dimension.height);
+            }
         }
     }
 
     public void renderBorders(Graphics g, HVisible visible, int state) {
-        Insets insets = getInsets(visible);
+        if (!visible.getBordersEnabled()) {
+            return;
+        }
+
+        // Only draw borders when focused
+        if ((state & HState.FOCUSED_STATE_BIT) == 0) {
+            return;
+        }
+
+        Insets insets = DEFAULT_INSETS;
         Color fg = visible.getForeground();
         Dimension dimension = visible.getSize();
 
         if (fg != null) {
             g.setColor(fg);
+            // Top border
             g.fillRect(0, 0, dimension.width, insets.top);
+            // Right border
             g.fillRect(dimension.width - insets.right, 0, insets.right, 
dimension.height);
+            // Bottom border
             g.fillRect(0, dimension.height - insets.bottom, dimension.width, 
insets.bottom);
+            // Left border
             g.fillRect(0, 0, insets.left, dimension.height);
         }
     }
 
     public void renderVisible(Graphics g, HVisible visible, int state) {
+        HTextLayoutManager tlm = visible.getTextLayoutManager();
+        if (tlm == null) {
+            return;
+        }
+
         String text = visible.getTextContent(state);
-        //Insets insets = getInsets(visible);
-        if (text == null) {
+        if (text == null || text.length() == 0) {
+            return;
+        }
+
+        Dimension size = visible.getSize();
+        Insets insets = getInsets(visible);
+
+        // Calculate available area for text
+        int availWidth = size.width - insets.left - insets.right;
+        int availHeight = size.height - insets.top - insets.bottom;
+
+        if (availWidth <= 0 || availHeight <= 0) {
             return;
         }
-        logger.unimplemented("renderVisible[text=" + text + "]");
+
+        tlm.render(text, g, visible, insets);
     }
 
     public void showLook(Graphics g, HVisible visible, int state) {
@@ -71,26 +104,139 @@ public class HTextLook implements HExtendedLook {
     }
 
     public void widgetChanged(HVisible visible, HChangeData[] changes) {
-        visible.repaint();
+        if (visible.isVisible()) {
+            visible.repaint();
+        }
+    }
+
+    private Dimension clampShortDimension(int width, int height) {
+        int w = Math.max(0, Math.min(width, Short.MAX_VALUE));
+        int h = Math.max(0, Math.min(height, Short.MAX_VALUE));
+
+        return new Dimension(w, h);
+    }
+
+    public Dimension getMinimumSize(HVisible visible) {
+        Insets insets = getInsets(visible);
+        int insetsWidth = (insets != null) ? insets.left + insets.right : 0;
+        int insetsHeight = (insets != null) ? insets.top + insets.bottom : 0;
+
+        // Step 1: If HDefaultTextLayoutManager, delegate to its 
getMinimumSize()
+        HTextLayoutManager tlm = visible.getTextLayoutManager();
+        if (tlm instanceof HDefaultTextLayoutManager) {
+            Dimension size = ((HDefaultTextLayoutManager) 
tlm).getMinimumSize(visible);
+            if (size != null && (size.width > 0 || size.height > 0)) {
+                return clampShortDimension(size.width + insetsWidth, 
size.height + insetsHeight);
+            }
+        }
+        // If not HDefaultTextLayoutManager or returns zero, proceed
+
+        // Steps 2-3: HTextLook does not support scaling, content sizing 
handled by TLM
+
+        // Step 4: If no content but default size set
+        Dimension defaultSize = visible.getDefaultSize();
+        if (defaultSize != null &&
+            defaultSize.width != HVisible.NO_DEFAULT_WIDTH &&
+            defaultSize.height != HVisible.NO_DEFAULT_HEIGHT) {
+            return clampShortDimension(defaultSize.width + insetsWidth, 
defaultSize.height + insetsHeight);
+        }
+
+        // Step 5: Implementation-specific minimum (0,0)
+        return new Dimension(insetsWidth, insetsHeight);
     }
 
-    public Dimension getMinimumSize(HVisible hvisible) {
-        logger.unimplemented("getMinimumSize");
-        return null;
+    public Dimension getPreferredSize(HVisible visible) {
+        Insets insets = getInsets(visible);
+        int insetsWidth = (insets != null) ? insets.left + insets.right : 0;
+        int insetsHeight = (insets != null) ? insets.top + insets.bottom : 0;
+
+        Dimension defaultSize = visible.getDefaultSize();
+
+        // Step 1: Check if default size is set (must check BEFORE delegating 
to TLM)
+        if (defaultSize != null) {
+            int w = defaultSize.width;
+            int h = defaultSize.height;
+
+            boolean hasDefaultWidth = (w != HVisible.NO_DEFAULT_WIDTH);
+            boolean hasDefaultHeight = (h != HVisible.NO_DEFAULT_HEIGHT);
+
+            if (hasDefaultWidth && hasDefaultHeight) {
+                // Full default size is set
+                return clampShortDimension(w + insetsWidth, h + insetsHeight);
+            }
+
+            // Handle NO_DEFAULT_WIDTH or NO_DEFAULT_HEIGHT cases
+            if (hasDefaultWidth || hasDefaultHeight) {
+                Dimension contentSize = getContentPreferredSize(visible);
+                if (!hasDefaultWidth) {
+                    w = contentSize.width;
+                }
+                if (!hasDefaultHeight) {
+                    h = contentSize.height;
+                }
+                return clampShortDimension(w + insetsWidth, h + insetsHeight);
+            }
+        }
+
+        // Step 2: If HDefaultTextLayoutManager, delegate to its 
getPreferredSize()
+        HTextLayoutManager tlm = visible.getTextLayoutManager();
+        if (tlm instanceof HDefaultTextLayoutManager) {
+            Dimension size = ((HDefaultTextLayoutManager) 
tlm).getPreferredSize(visible);
+            if (size != null && (size.width > 0 || size.height > 0)) {
+                return clampShortDimension(size.width + insetsWidth, 
size.height + insetsHeight);
+            }
+        }
+        // If not HDefaultTextLayoutManager or returns zero, proceed
+
+        // Steps 3-4: HTextLook does not support scaling
+
+        // Step 5: Return current size of HVisible
+        return visible.getSize();
     }
 
-    public Dimension getPreferredSize(HVisible hvisible) {
-        logger.unimplemented("getPreferredSize");
-        return null;
+    /**
+     * Helper method to get preferred content size from the text layout 
manager.
+     */
+    private Dimension getContentPreferredSize(HVisible visible) {
+        HTextLayoutManager tlm = visible.getTextLayoutManager();
+        if (tlm instanceof HDefaultTextLayoutManager) {
+            Dimension size = ((HDefaultTextLayoutManager) 
tlm).getPreferredSize(visible);
+            if (size != null && (size.width > 0 || size.height > 0)) {
+                return size;
+            }
+        }
+        // Fallback: use current size (without insets, as caller adds them)
+        Dimension currentSize = visible.getSize();
+        Insets insets = getInsets(visible);
+        int w = currentSize.width - (insets != null ? insets.left + 
insets.right : 0);
+        int h = currentSize.height - (insets != null ? insets.top + 
insets.bottom : 0);
+        return new Dimension(Math.max(0, w), Math.max(0, h));
     }
 
-    public Dimension getMaximumSize(HVisible hvisible) {
-        logger.unimplemented("getMAximumSize");
-        return null;
+    public Dimension getMaximumSize(HVisible visible) {
+        Insets insets = getInsets(visible);
+        int insetsWidth = (insets != null) ? insets.left + insets.right : 0;
+        int insetsHeight = (insets != null) ? insets.top + insets.bottom : 0;
+
+        // Step 1: If HDefaultTextLayoutManager, delegate to its 
getMaximumSize()
+        HTextLayoutManager tlm = visible.getTextLayoutManager();
+        if (tlm instanceof HDefaultTextLayoutManager) {
+            Dimension size = ((HDefaultTextLayoutManager) 
tlm).getMaximumSize(visible);
+            if (size != null && (size.width > 0 || size.height > 0)) {
+                return clampShortDimension(size.width + insetsWidth, 
size.height + insetsHeight);
+            }
+        }
+        // If not HDefaultTextLayoutManager or returns zero, proceed
+
+        // Steps 2-3: HTextLook does not support scaling
+
+        // Step 4: No content, return Short.MAX_VALUE
+        return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
     }
 
     public boolean isOpaque(HVisible visible) {
-        if (visible.getBackgroundMode() != 1) {
+        // Component is opaque if background fill is enabled and has opaque 
background color
+        if (visible.getBackgroundMode() != HVisible.BACKGROUND_FILL) {
             return false;
         }
 
@@ -104,10 +250,8 @@ public class HTextLook implements HExtendedLook {
 
     public Insets getInsets(HVisible visible) {
         if (!visible.getBordersEnabled()) {
-            return new Insets(0, 0, 0, 0);
+            return NO_INSETS;
         }
-        return new Insets(2, 2, 2, 2);
+        return DEFAULT_INSETS;
     }
-
-    private static final Logger logger = 
Logger.getLogger(HTextLook.class.getName());
 }



View it on GitLab: 
https://code.videolan.org/videolan/libbluray/-/commit/afda50959e81cd331d7d5a8ac68da9b358130325

-- 
View it on GitLab: 
https://code.videolan.org/videolan/libbluray/-/commit/afda50959e81cd331d7d5a8ac68da9b358130325
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance
_______________________________________________
libbluray-devel mailing list
[email protected]
https://mailman.videolan.org/listinfo/libbluray-devel

Reply via email to