2011-06-28 15 views
6

से एक साधारण जीयूआई बनाएं जिसमें कोई वास्तविक लाइब्रेरी उपलब्ध नहीं है, और निर्देशांक (x, y, xx, yy) के प्रदर्शन ऑब्जेक्ट (x, y, xx, yy) के अलावा नंगे-न्यूनतम ग्राफिक्स (i, y), I मैं एक साधारण gui बनाने की कोशिश कर रहा हूं।स्क्रैच

क्या कोई मुझे संदर्भ में इंगित कर सकता है जहां मैं स्क्रीन पर ऑब्जेक्ट्स का एक सेट प्रदर्शित करने में शामिल तर्कसंगत सिद्धांतों को समझ सकता हूं, और चयनित ऑब्जेक्ट को हाइलाइट कर सकता हूं, जिससे उपयोगकर्ता ऑब्जेक्ट्स के बीच नेविगेट कर सकते हैं और प्रत्येक ऑब्जेक्ट पर हाइलाइट करना शुरू करें। ऐसा लगता है कि यह करना आसान होना चाहिए, लेकिन मैं समझना चाहता हूं कि लोग इस बारे में क्या सोचते हैं।

obj.highlight() जहां obj.highlight() जैसी विधि के साथ कोई ऑब्जेक्ट कैसे बनाएगा हाइलाइट टर होगा अन्य सभी वस्तुओं में हाइलाइटिंग बंद? क्या कोई ऑब्जेक्ट्स की सरणी के माध्यम से अगले लूप के लिए बस करेगा, वर्तमान ऑब्जेक्ट को छोड़ देगा, हाइलाइटिंग बंद कर देगा और फिर वर्तमान ऑब्जेक्ट को सही पर सेट करेगा? एक ऑब्जेक्ट को एक पारदर्शी केंद्र के साथ चयनित ऑब्जेक्ट के शीर्ष पर खींचकर हाइलाइटिंग पूरा किया जाएगा।

यह एक एकल थ्रेड सिस्टम है, (लेकिन एसिंक प्रोसेसिंग की एक छोटी राशि की अनुमति देता है)।

मैं वैचारिक विचारों के लिए और अधिक देख रहा हूं लेकिन वीबी में कोड जो मालिकाना ग्राफिक्स कॉल का उपयोग नहीं करता है उपयोगी हो सकता है।

उत्तर

2

खैर कि एक सवाल है कि एक लाख मायनों में जवाब दिया जा सकता ... :)

लेकिन जब तक आप पिक्सल (या दूर से ऐसा लगता है कि कुछ भी) आकर्षित कर सकते हैं, तो आप एक जीयूआई आकर्षित कर सकते हैं। यदि आपके पास ऑब्जेक्ट उन्मुख भाषा है, तो मैं वर्तमान ऑब्जेक्ट को हाइलाइट और हाइलाइट करने का चयन नहीं करूंगा। अगर मैं फोकस करता हूं और इससे फोकस हटा देता हूं, तो ऑब्जेक्ट स्वयं तय करेगा कि इसे फिर से खींचा जाना चाहिए और यह कैसे किया जाना चाहिए।

यदि आप किसी ऑब्जेक्ट को किसी प्रकार के कंटेनर में रखे हैं तो आप स्वचालित रूप से पिछले ऑब्जेक्ट को फ़ोकस कर सकते हैं। जब आप एक नेविगेशन कुंजी (टैब की तरह) दबाते हैं या माउस बटन दबाते हैं, तो वह कंटेनर उस संदेश को संसाधित कर सकता है और अगली ऑब्जेक्ट को फ़ोकस कर सकता है और अंतिम ऑब्जेक्ट को फ़ोकस कर सकता है।

इसे कुछ प्रोग्रामिंग की आवश्यकता है, लेकिन अवधारणा काफी आसान है। जब आप इसे अच्छा प्रदर्शन करना चाहते हैं, तो यह कठिन हो जाता है, सभी प्रकार की नींव और संक्रमण हो ... लेकिन जैसा कि मैंने कहा, अवधारणा सरल है और आपको इसे करने के लिए ओओ की भी आवश्यकता नहीं होगी, हालांकि यह शायद आप एक बहुत साफ परिणाम। मुझे लगता है कि अगर मुझे जरूरत पड़ती है तो मैं बरसात के दोपहर में डॉस बैच में एएससीआईआई आधारित जीयूआई प्रोग्राम कर सकता हूं।

3

मैंने एक छोटा नमूना ऐप कोड किया है जो .NET C# का उपयोग करके फ़ॉर्म पर पेंट करके अपना नियंत्रण ढांचा करता है। बस इस परिणाम के साथ सरल कुछ:

enter image description here

मैं रिकर्सिवली सभी नियंत्रण को अक्षम और क्लिक किया एक टॉगल करके IsSelected किया है। window.MouseUp += (sender, arg) => के साथ भाग देखें।

चयन माउस या टैब कुंजी के माध्यम से जा सकता है।

कोड दृष्टिकोण अन्य भाषाओं के लिए पोर्टेबल होना चाहिए, और वीबी.Net के लिए ऑनलाइन-अनुवाद योग्य होना चाहिए।

कोड के प्रासंगिक टुकड़ा:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 
using System.Drawing; 
using System.Threading; 
using System.Threading.Tasks; 

namespace CustomGUI 
{ 
    static class Program 
    { 
     /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Form window = new Form1(); 
      window.BackColor = Color.Gray; 

      Graphics api = window.CreateGraphics(); 

      GUIControl form = new GUIControl(); 
      form.Location = new Point(30,30); 
      form.Size = new Size(200, 300); 

      GUIControl control1 = new GUIControl(); 
      control1.Location = new Point(0, 0); 
      control1.Size = new Size(200, 130); 
      control1.Background = Color.Blue; 

      GUIControl control11 = new GUIControl(); 
      control11.Location = new Point(140, 30); 
      control11.Size = new Size(30, 30); 
      control11.Background = Color.Red; 

      GUIControl control12 = new GUIControl(); 
      control12.Location = new Point(30, 30); 
      control12.Size = new Size(30, 30); 
      control12.Background = Color.Red; 
      control12.BorderColor = Color.Green; 
      control12.BorderWidth = 5; 

      GuiLabel control2 = new GuiLabel(); 
      control2.Location = new Point(10, 200); 
      control2.Size = new Size(180, 30); 
      control2.Background = Color.Green; 
      control2.Text = "Hello World!"; 

      control1.AddChild(control11); 
      control1.AddChild(control12); 

      form.AddChild(control1); 
      form.AddChild(control2); 

      window.MouseUp += (sender, arg) => 
      { 
       // hit test the control where the mouse has landed 
       IGUIContainer control = form.HitTest(arg.Location); 
       if (control != null) 
       { 
        // recursive on all controls 
        foreach (var ct in (new IGUIContainer[] { form }).Traverse(c => c.Controls)) 
        { 
         //deselecting all others 
         if (ct != control) ct.IsSelected = false; 
        } 
        control.IsSelected = !control.IsSelected; 
       } 
       window.Invalidate(); // force paint 
      }; 

      window.KeyUp += (sender, key) => 
      { 
       if (key.KeyCode == Keys.Tab && key.Modifiers == Keys.None) 
       { 
        var selected = (new IGUIContainer[] { form }).Traverse(c => c.Controls).FirstOrDefault(c => c.IsSelected); 

        IGUIContainer parent; 

        if (selected == null) 
        { 
         parent = form; 
        } 
        else 
        { 
         parent = selected; 
        } 

        IGUIContainer control; 

        if (parent.Controls.Count > 0) 
        { 
         control = parent.Controls[0]; 
        } 
        else 
        { 
         control = GUIControl.Next(parent); 
        } 

        if (control == null) control = form; 

        foreach (var ct in (new IGUIContainer[] { form }).Traverse(c => c.Controls)) 
        { 
         if (ct != control) ct.IsSelected = false; 
        } 

        control.IsSelected = true; 

        window.Invalidate(); 
       } 
      }; 

      window.Paint += (sender, args) => 
      { 
       form.Draw(api, new Point(0,0)); 
      }; 

      Application.Run(window); 
     } 
    } 
} 

सभी की जरूरत वर्गों और इंटरफेस:

IDrawable:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 

namespace CustomGUI 
{ 
    public interface IDrawable 
    { 
     Point Location { get; set; } 
     Size Size { get; set; } 
     Rectangle GetRealRect(Point origin); 
     void Draw(Graphics gfxApi, Point origin); 
    } 
} 

IGUIContainer:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 

namespace CustomGUI 
{ 
    delegate void SelectionChangedHandler(object sender, bool newIsSelected); 

    interface IGUIContainer : IUIElement 
    { 
     IGUIContainer Parent { get; set; } 
     List<IGUIContainer> Controls { get; } 
     void AddChild(IGUIContainer child); 
     bool IsSelected { get; set; } 
     event SelectionChangedHandler SelectionChanged; 
     IGUIContainer HitTest(Point mouseCoord); 
    } 
} 

UIElement:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 
using System.Diagnostics; 

namespace CustomGUI 
{ 
    abstract class UIElement : IUIElement 
    { 
     private Point _location; 
     private Size _size; 
     private Color _background; 
     private Color _foreground; 
     private Color _borderColor; 
     private int _borderWidth; 

     public UIElement() 
     { 
      _foreground = Color.Black; 
      _background = Color.White; 
      _borderColor = Color.Transparent; 
     } 

     public Point Location 
     { 
      get 
      { 
       return _location; 
      } 
      set 
      { 
       _location = value; 
      } 
     } 

     public Size Size 
     { 
      get 
      { 
       return _size; 
      } 
      set 
      { 
       _size = value; 
      } 
     } 

     public virtual void Draw(Graphics drawingApi, Point origin) 
     { 

      Rectangle inside = GetRealRect(origin); 

      Pen borderPen = new Pen(new SolidBrush(_borderColor), _borderWidth); 
      drawingApi.FillRectangle(new SolidBrush(_background), inside); 
      drawingApi.DrawRectangle(borderPen, inside); 
     } 

     public Rectangle ClientRect 
     { 
      get 
      { 
       return new Rectangle(_location, _size); 
      } 
     } 


     public Color Background 
     { 
      get 
      { 
       return _background; 
      } 
      set 
      { 
       _background = value; 
      } 
     } 

     public Color Foreground 
     { 
      get 
      { 
       return _foreground; 
      } 
      set 
      { 
       _foreground = value; 
      } 
     } 


     public Rectangle GetRealRect(Point origin) 
     { 
      int left = ClientRect.Left + origin.X; 
      int top = ClientRect.Top + origin.Y; 
      int width = ClientRect.Width; 
      int height = ClientRect.Height; 

      Debug.WriteLine("GetRealRect " + left + ", " + top + ", " + width + ", " + height); 

      return new Rectangle(left, top, width, height); 
     } 


     public int BorderWidth 
     { 
      get 
      { 
       return _borderWidth; 
      } 
      set 
      { 
       _borderWidth = value; 
      } 
     } 

     public Color BorderColor 
     { 
      get 
      { 
       return _borderColor; 
      } 
      set 
      { 
       _borderColor = value; 
      } 
     } 
    } 
} 

GUIControl:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 

namespace CustomGUI 
{ 
    class GUIControl : UIElement, IGUIContainer 
    { 
     private IGUIContainer _parent; 
     private List<IGUIContainer> _controls = new List<IGUIContainer>(); 
     private bool _isSelected; 

     public List<IGUIContainer> Controls 
     { 
      get 
      { 
       return _controls; 
      } 
     } 

     public override void Draw(Graphics api, Point origin) 
     { 
      Point original = origin; 

      base.Draw(api, origin); 

      origin.Offset(this.Location); 

      foreach (var ctrl in Controls) 
      { 
       ctrl.Draw(api, origin); 
      } 

      if (IsSelected) 
      { 
       Pen selection = new Pen(Color.Yellow, 3); 
       selection.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; 
       api.DrawRectangle(selection, GetRealRect(original)); 
      } 

     } 

     public IGUIContainer HitTest(Point coord) 
     { 
      Point newOrigin = coord; 
      newOrigin.Offset(-this.Location.X, -this.Location.Y); 

      foreach (var ctrl in Controls) 
      { 
       IGUIContainer hit = ctrl.HitTest(newOrigin); 
       if (hit != null) 
       { 
        return hit; 
       } 
      } 

      return ClientRect.Contains(coord) ? this : null; 
     } 

     public bool IsSelected 
     { 
      get 
      { 
       return _isSelected; 
      } 
      set 
      { 
       _isSelected = value; 

       if (SelectionChanged != null) 
       { 
        SelectionChanged(this, _isSelected); 
       } 
      } 
     } 

     public event SelectionChangedHandler SelectionChanged; 

     public void AddChild(IGUIContainer child) 
     { 
      // if you need to implement event propagation this is the place to attach them to children 
      child.Parent = this; 
      Controls.Add(child); 
     } 

     public IGUIContainer Parent 
     { 
      get 
      { 
       return _parent; 
      } 
      set 
      { 
       _parent = value; 
      } 
     } 

     public static IGUIContainer Next(IGUIContainer self) 
     { 
      if (self.Parent != null && 
       self.Parent.Controls.Count - 1 > self.Parent.Controls.IndexOf(self)) 
      { 
       return self.Parent.Controls[self.Parent.Controls.IndexOf(self) + 1]; 
      } 
      else if (self.Parent != null) 
      { 
       return Next(self.Parent); 
      } 
      else 
      { 
       return null; 
      } 
     } 
    } 
} 

GUILabel:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Drawing; 

namespace CustomGUI 
{ 
    class GuiLabel : GUIControl 
    { 
     public string Text { get; set; } 
     public Font Font { get; set; } 

     public GuiLabel() 
     { 
      Font = new Font(new FontFamily("Tahoma"), 12, FontStyle.Regular);    
     } 

     public override void Draw(System.Drawing.Graphics api, System.Drawing.Point origin) 
     { 
      base.Draw(api, origin); 

      Rectangle controlRect = GetRealRect(origin); 
      SizeF size = api.MeasureString(Text, Font); 

      Point textPosition = new Point(controlRect.Location.X + (int)(controlRect.Width - size.Width)/2, 
             controlRect.Location.Y + (int)(controlRect.Height - size.Height)/2); 

      api.DrawString(Text, Font, new SolidBrush(Foreground), textPosition); 
     } 
    } 
} 

एक्सटेंशन (Traverse विधि प्रत्यावर्तन समतल के लिए):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace CustomGUI 
{ 
    static class Extensions 
    { 
     public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse) 
     { 

      foreach (T item in source) 
      { 

       yield return item; 

       IEnumerable<T> seqRecurse = fnRecurse(item); 

       if (seqRecurse != null) 
       { 

        foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse)) 
        { 

         yield return itemRecurse; 

        } 

       } 

      } 

     } 
    } 
} 
संबंधित मुद्दे