[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Miniwindows
. . -> [Subject]  Widget framework

Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?
(New message)
Subject: Widget framework
Name:
Your forum user name.
Register forum user name
Password:
Your forum password.
Forgotten password?
Message:
Message to be posted (in English, please).
Forum codes:
Check this if your message uses 'forum codes' or templates (auto-detected for new posts).
Forum codes Templates

Save this message ...


Subject review (reverse sequence)

Pages: 1  2 

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sun 03 Jan 2010 08:43 PM (UTC)  quote  ]
Message
Thanks! I appreciate it. :)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (18,770 posts)  [Biography] bio   Forum Administrator
Date Sun 03 Jan 2010 08:42 PM (UTC)  quote  ]
Message
When you believe it is ready for release I can put a link to your stuff on the miniwindow introduction page.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sat 02 Jan 2010 06:24 PM (UTC)  quote  ]
Message
It's been a while since I've posted directly about this, so I thought I'd drop in for an update. Widget composition is fully working, by drawing each widget in its own invisible miniwindow separately, and collating them with their parents' invisible canvases to create the final product.

Hotspot support is nearly complete as well. Only the drag-related handlers are unsupported, but that's only because I'm still pondering the direction of the hotspot abstraction layer. Otherwise, hotspots appear to work very well, having kept a hotspot-heavy TicTacToe plugin up to date.

I would really appreciate it if anyone could download the framework and mess around with it. It's hard to continue working without any feedback, because I'm not sure how things will be used outside simple development testing. There are installation instructions on the wiki page of my GitHub repository, and I've pasted my TicTacToe plugin in full elsewhere [1].

[1]: http://www.mudbytes.net/index.php?a=topic&t=2355&p=40108#p40108

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Thu 10 Dec 2009 11:03 PM (UTC)  quote  ]

Amended on Thu 10 Dec 2009 11:06 PM (UTC) by Twisol

Message
I've wrapped most/all of the Window*() functions into the Window base type, acting as a layer between the widget code and MUSHclient. I aimed for simplicity and intuitiveness where I could; for example, I split the WindowCircleOp() and WindowImageOp() functions into multiple methods, each corresponding to a separate value of the 'action' parameter.

After a long while deliberating my options, I felt that wrapping the Window*() functionality this way would be the easiest way to implement window "frames" similar to those surrounding windows in Windows. For simplicity, I wanted (0,0) to correspond to the upper-left edge of the "inside" of the frame, rather than the upper-left of the frame itself. This is a similar setup to the Win32 behavior anyways, though it will still be entirely possible to draw on the borders by supplying negative coordinates.

The only part I'm not really happy with is WindowRectOp; I'm not really sure how to break that down. WindowCircleOp allows for the drawing of rectangles, covering RectOp's actions 1 and 2, and I separately created an InvertRectangle() method to cover action 3. The rest I'm not sure about.


While there certainly aren't many widgets available yet, the Window layer alone might be fun to play with. I'd appreciate it if anyone else could test it out and let me know what their feelings are.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Tue 01 Dec 2009 09:39 PM (UTC)  quote  ]
Message
Since I've already mostly set up the object/class system and organization, feel free to create your own widgets from what I have so far. If they're general-purpose enough (like a listbox), I'd be glad to add them to the framework. Check out CharacterGrid and Gauge for examples of how to derive a widget.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Cage_fire_2000   USA  (119 posts)  [Biography] bio
Date Tue 01 Dec 2009 09:28 PM (UTC)  quote  ]

Amended on Tue 01 Dec 2009 09:38 PM (UTC) by Cage_fire_2000

Message
Dang, I was working on something like this, thinking that an object oriented interface would be easier, but coding it in the first place is hard, and there's lots of stuff I don't really know. I was thinking it could make it so I could setup labels and buttons really easy, you know standard controls, maybe a listbox, stuff like that, but the problem is changing what's displayed, if you don't have a background drawn underneath, or you want to move the control somewhere, you need to clear the entire window and redraw everything, so you have to record everything to draw, and what order to draw it. Frankly, making a module for everything would probably be like 1000 times harder than any code you'd actually need to make with it(at least what I've done so far), and still might not do everything you'd want it to. I suppose a basic one wouldn't be two hard, where you simply put all the miniwindow functions in a general class, I already started something like that although I found it hard to continue working on it. It also has the problem of eating up memory making objects for everything. I find myself wondering whether it's worth it to make. Then again I do get bored easily when I have to figure out the mechanics of everything myself.

Edit: Hmm, to be honest it's the drawing order I was having a hard time figuring out, I suppose the rest of it you could have a table of controls on the form, with a field for the type of control, any miscellaneous data, etc. Hmm, I suppose... if it's an array, then the order of the array could be the z-order, but then I'd need another table to lookup controls by name... It all gives me a headache which is why I haven't gotten very far.

Edit: Not to mention you need to have it check whether the control or whatever still exists or not. God, I need to stop thinking about it before my head explodes.
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Tue 01 Dec 2009 07:24 PM (UTC)  quote  ]
Message
Thanks! I'm glad you like the idea. ^_^

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio   Moderator
Date Tue 01 Dec 2009 07:23 PM (UTC)  quote  ]
Message
I think that this is really quite nifty -- I look forward to playing around with it more when I get the chance. Having a solid framework for common widgets will make developing "sub-interfaces" much more efficient.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Tue 01 Dec 2009 08:56 AM (UTC)  quote  ]

Amended on Tue 01 Dec 2009 08:57 AM (UTC) by Twisol

Message
I've just committed a version that implements a very small subset of WillFa's InfoBox functionality. It's barely even begun, in my opinion, but some of the other functionality in InfoBox (like the gauges being collected together under a common frame) are likely going to be implemented as separate widgets altogether.

Not to be conceited, but I particularly like my implementation of the gauge effects. I think it makes it rather easy to define new (and potentially complex) gauge effects, and it simplifies the actual drawing code. I left off implementing fixed gradients because it was somewhat difficult for me to transpose the variables/logic used in InfoBox to my model, but I did create a substitute 'meter' effect, which simply places a line at the point of value.

EDIT: Latest source can always be found at my GitHub respository; see [1].


[1] http://github.com/Twisol/MUSHclient-MWidget

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Tue 24 Nov 2009 09:54 PM (UTC)  quote  ]
Message
Here is a demo plugin that lets you play TicTacToe in a miniwindow. My implementation of the game itself is undoubtedly rather bad (note the CheckWin/CheckRow functions), but the purpose of the plugin is just to showcase the CharacterGrid widget.


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="TicTacToe"
   author="Soludra"
   id="03829336f30e9f2dcace86e9"
   language="Lua"
   purpose="Play a game of Tic Tac Toe!"
   date_written="2009-11-22 07:46:00"
   requires="4.43"
   version="1.0"
/>

<!--  Script  -->

<script>
<![CDATA[

CharacterGrid = require("MWidget.CharacterGrid")

-- Defines the default grid font.
TICTACTOE_FONT = "Lucida Console"

players = {
  [1] = {
    piece = 'X',
    color = 0x00FF00,
    lastmove = nil,
  },
  [2] = {
    piece = 'O',
    color = 0x0000FF,
    lastmove = nil,
  },
}
current_player = 1

-- cell we're hovering over now
hovered = nil

-- has the game been finished?
done = false

CheckRow = function(cell1, cell2, cell3)
  if cell1.char ~= ' ' and
     cell1.char == cell2.char and
     cell2.char == cell3.char then
    cell1.forecolor, cell2.forecolor, cell3.forecolor = 0xFF0000, 0xFF0000, 0xFF0000
    return true
  else
    return false
  end
end

CheckWin = function()
  done = CheckRow(grid:Cell(1, 1), grid:Cell(1, 2), grid:Cell(1, 3)) or
         CheckRow(grid:Cell(2, 1), grid:Cell(2, 2), grid:Cell(2, 3)) or
         CheckRow(grid:Cell(3, 1), grid:Cell(3, 2), grid:Cell(3, 3)) or
         CheckRow(grid:Cell(1, 1), grid:Cell(2, 1), grid:Cell(3, 1)) or
         CheckRow(grid:Cell(1, 2), grid:Cell(2, 2), grid:Cell(3, 2)) or
         CheckRow(grid:Cell(1, 3), grid:Cell(2, 3), grid:Cell(3, 3)) or
         CheckRow(grid:Cell(1, 1), grid:Cell(2, 2), grid:Cell(3, 3)) or
         CheckRow(grid:Cell(3, 1), grid:Cell(2, 2), grid:Cell(1, 3))
  return done
end

CellClick = function(flags, id)
  if done then
    return
  end
  
  local cell = grid:HotspotToCell(id)
  
  if cell.char ~= " " then
    return
  end
  
  local player = players[current_player]
  if player.lastmove then
    player.lastmove.backcolor = 0xFFFFFF
  end
  
  cell.char = player.piece
  cell.backcolor = player.color
  
  CheckWin()
  
  player.lastmove = cell
  current_player = (current_player%2) + 1
  grid:Draw()
end

CellFocus = function(flags, id)
  if done then
    return
  end
  
  local cell = grid:HotspotToCell(id)
  
  if cell.char ~= " " then
    return
  end
  
  cell.forecolor = players[current_player].color
  cell.char = players[current_player].piece
  
  hovered = id
  grid:Draw()
end

CellBlur = function(flags, id)
  if done then
    return
  end
  
  if id ~= hovered then
    return
  end
  local cell = grid:HotspotToCell(hovered)
  
  cell.forecolor = 0x000000
  cell.char = ' '
  
  hovered = nil
  grid:Draw()
end

Reset = function()
  current_player = 1
  done = false
  
  grid:ResetGrid()
  
  for y = 1, 3 do
    for x = 1, 3 do
      local cell = grid:Cell(x, y)
      cell.forecolor = 0x000000
      cell.hotspot = {
        mouseup = "CellClick",
        mouseover = "CellFocus",
        cancelmouseover = "CellBlur",
      }
    end
  end
  
  grid:Draw()
end

OnPluginInstall = function()
  grid = CharacterGrid.new(3, 3)
  grid:Anchor(12)
  grid:Font(TICTACTOE_FONT, 15)
  grid.backcolor = 0xFFFFFF

  Reset()
  grid:Show()
end

OnPluginClose = function()
  grid:Destroy()
end

OnPluginEnable = OnPluginInstall
OnPluginDisable = OnPluginClose

]]>
</script>
</muclient>


The grid appears by default in the center of the screen. Hovering over any available space will display the current player's color/piece. It highlights each player's last move, and highlights a winning line in blue (and also locks the grid).

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sun 22 Nov 2009 12:31 AM (UTC)  quote  ]
Message
I've opened a git repository [1] for the widget framework, in case anyone wants to collaborate. Big thanks to Will for his input so far, also!


[1]: http://github.com/Twisol/MUSHclient-MWidget

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by WillFa   USA  (517 posts)  [Biography] bio
Date Fri 20 Nov 2009 05:03 AM (UTC)  quote  ]

Amended on Fri 20 Nov 2009 05:12 AM (UTC) by WillFa

Message
Twisol, Have at it. :)


The thing is that Infobox already does most things with miniwindows (I haven't added dragging, and there's no provisions for drawing bitmaps/pngs).

Your grid widget/mapmover can be implemented with InfoBox by just futzing with a couple of values...

In your Script file:

require "InfoBox"
MW = InfoBox:New("Test")
MW.Bar.barStyle = 0 -- no frame or gauge
MW:Font("Dina", 9) -- monospaced font
MW.padding = 0 -- smoosh lines together

local LookupColors = {}
for k,v in pairs(MW.ansiColors) do
  LookupColors[v] = k
end
for k,v in pairs(MW.customColourCodes) do
  LookupColors[v]=k
end


In your MapStart trigger:

MW.Bars={}


In your MapDataLine trigger:

local Caption = ""
for k,v in ipairs(TriggerStyleRuns) do
  if not LookupColors[v.textcolour] then
    -- Code to append to LookupColors if not found
  end
  Caption = string.format("%s@%s%s", Caption, LookupColors[v.textcolour], v.text)
end
MW:AddBar(Caption)


In your MapFinish trigger:

MW:Update()



The module really does more than just gauges, though it's original intention was to move the InfoBar function calls into a miniwindow
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Fri 20 Nov 2009 03:40 AM (UTC)  quote  ]
Message
@WillFa: It would be great to integrate those components into a Widget framework and make them reusable among other widgets. Would you mind if I tried adapting your code to the barebones demonstration I posted above (and perhaps took a few of your ideas)?

@Blainer: Yes. I went through that with a C++ class I called cConsole, when later I realized I could emulate nearly all of its output functionality with two custom stream manipulators (one for position, the other for color) which only took maybe ten lines of actual code...

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Blainer   (191 posts)  [Biography] bio
Date Fri 20 Nov 2009 01:56 AM (UTC)  quote  ]
Message
Don't you hate when you write 3000 lines of code then find out there's a better way...
[Go to top] top

Posted by WillFa   USA  (517 posts)  [Biography] bio
Date Thu 19 Nov 2009 10:06 PM (UTC)  quote  ]
Message
Shameless plug:

Template:post=9097 Please see the forum thread: http://gammon.com.au/forum/?id=9097.
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


5,835 views.

This is page 2, subject is 2 pages long:  [Previous page]  1  2 

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]