Download
(17Kb)
Download
Updated: 11-29-09 06:18 PM
Pictures
File Info
Updated:11-29-09 06:18 PM
Created:09-03-09 01:04 AM
Downloads:3,475
Favorites:27
MD5:

Tweaker

Version: 1.2.2
by: RaeVanMorlock [More]

Latest News

11/15

I republished my first Tweaker tutorial for the new site: http://www.tweakeraddon.com/tuts/modifying-the-viewport

There are some other tutorials listed in the menu, but they're not created yet. All the tut and doc stuff is still static at this point and it takes awhile to create.


11/1

Looking back at how big Tweaker grew with version 1.2, it struck me that some documentation is going to be handy. I certainly don't expect people to read through all the code in order to see what's available, but that's about all that you can do at the moment. Well, that, and using /dump can give a rundown of what's available -- /dump TweakerColorizer, for instance, will show all the properties and methods and what-not of that class.

But that's still a pain, so I'm working on the documentation. It's not polished yet, but the data for TweakerColorizer is up. Let me know what ya think.

http://tweakeraddon.appspot.com/docs/TweakerColorizer

I'm also in the process of getting http://www.tweakeraddon.com to work but these DNS and CNAME things can take up to 2 days to propagate.

Update
I had some fun with MooTools and made the menus on the doc page move up and down with the page, and I'm loving the results. If your browser window is too small to fit the entire menu, it gets really smart and only moves as needed, to either the top or bottom edge depending on the direction you scrolled.

I also said 50 Hail Marys and opened up IE to see how the page would look. I swear, that browser is the worst thing to happen to the web. I managed to get the menus moving just fine in IE8, but the code highlighting... well, it's not pretty. Apparently, IE normalizes their stored HTML, not just what's rendered, so when Javascript tries to access it, it gets the normalized version. This means when my script goes to parse the code, white space is all reduced to a single space character. That means not only can I not display line breaks and tabs, but I can't even detect them in order to know, say, when a comment ends.

Thank you, Microsoft, for saving me those precious bytes of memory.

Get a real browser

(Is it ironic that my IE just froze up?)


10/29

Tweaker 1.2 is being released today. It's been stable for quite some time for myself now, and the other features that are pending for Tweaker can wait for another version. My time has been scarce lately and it's already been far too long of a wait. The website will hopefully be more of a focus now as I try to get it going so that Tweaker can be better documented. In the meantime, feel free to browse the source code or use the /dump command to see what functionality is available.

/dump Tweaker
/dump TweakerColorizer
/dump TweakerLogger
/dump TweakerSlash

TWEAKER 1.2 CHANGELOG

File Structure

- Users will no longer be confined to creating their tweaks in config.lua. Tweaks can be made and registered to Tweaker at any time. As such, common tweaks will be able to be packaged and distributed. You may also want to consider making a MyTweaks addon for your custom tweaks. This change will add overhead, but I'll keep it as minimal as possible.

- config.lua will be loaded after Tweaker, so people using config.lua can make use of the Tweaker Global API (which will be more important now than before)

Development Tools

Coloring

- It's a common task, why not have a tool for it? I've found myself using it throughout various modules.

- TweakerColorizer:new() to instantiate, new() takes an optional table of name/color pairs, where name is any string and color is a series of 6 hexadecimal digits following standard notation, rrggbb, such that ffffff is white and 000000 is black. (I should probably update this in the future to take 6 or 8 digits so alpha can optionally be included.)

- Colorizers can be instantiated from other colorizers, and thus inherit their colors. So if a = TweakerColorizer:new() and a defines a color, burple, and b is a new colorizer created from a, such that b = a:new(), then b will also have access to burple and any other colors that a has, regardless of them being added before or after b's instantiation. You may also redefine colors on b to have them take precedence. You'll find that I frequently name colors in my modules according to functionality, so the Logger module has a color named trace that's used for trace messages. Anything inheriting from my logger module will also have a trace color that can then be set to whatever color the person wants to use for his/her trace messages.

- :Apply(color, string, ...) takes a color, by name, and applies it to the string. If additional arguments are included, string is assumed to be a formatstring, and string.format(formstring, ...) is called. If color is not the name of a defined color, it's treated as the color itself. The resultant string is returned.

- :RegexApply(color, regex, string, ...) Here, a regex pattern is also included. Any characters matching the pattern will have the color applied to them in the returned string result.

- Many more, check the files or /dump TweakerColorizer

Logging

- Enhanced logging features. I've borrowed the logging style used in the log4j java module to implement levels of logging. Tweaks will be able to define their own level of logging separate from the global default so users can get details on a particular tweak that they're working on and not every tweak in their repertoire.

- Tweaker itself will have more log messages than before, and users will be able to use Tweaker to generate logging messages for their tweaks.

- Log messages can be throttled. A global setting will be available to determine how often the same log message can be repeated, and disabling the setting will disable the throttling. (I'm not too sure about keeping this. Since trace messages can be somewhat generic and inferred by their context, the throttling can remove some that you expect to see when debugging.) Removed

- TweakerLogger is a new class that can be instantiated via TweakerLogger:new(). Users may use Tweaker's log via Tweaker.log or instantiate their own if need be.

Slash Command Handling

- TweakerSlashCommand:new() and TweakerSlashCommandHandler:new() to create a command and a handler, respectively.

- SlashCommand objects should have the following properties: commands (array of strings, such as "apples" or "oranges", to follow the base slash command), help (the help text to include when using the help command, briefly explaining what the command does, such as "gives the requested number of apples, defaults to 1"), args (the args that can be included after the command, such as "[<any digit>]" to say that any digit may optionally be included), call (the function to call when the command is requested by the user in order to process any arguments)

- call currently supports only one arguments, text, and it's up to the call function to interpret and parse the text, or throw an error.

- SlashCommandHandler objects should be defined with two properties: Name and Commands (notice the capitalization here). Name is how the handler will identify itself to the end user. For instance, "Tweaker." Commands is an array of slash commands, such as { "/tweaker", "/tweak" }

- All new SlashCommandHandler objects have a default help command, which can be called simply via /slash help or for detailed info via /slash help command.

/dump command

- Enhanced /dump command (can be turned off). I love that WoW finally includes its own /dump command, but I think it's ugly. I've created one similar to what AceConsole offers, but it's currently using 300-350 lines of code instead of the 2500-3000 lines that Ace uses.

The Tweaker Process

- Tweaks are no longer created at PLAYER_LOGIN. They are put into a queue and created as soon as all of their requirements are met: ie. Parent widget must exist, Template tweaks must have been processed, and Requirements widgets must all exist.

- Tweaker_Data has been removed. Use Tweaker.RegisterTweak({}) and Tweaker.RegisterTweaks({{}, {}, {}})

Tweak Attributes

Widget Names

- Tweaks will no longer be given a default name if one is not supplied, the resulting widget will just be unnamed and users will not be able to reference it. With the new structure, there is no simple top-to-bottom order of tweaks, so there's no way of consistently naming them. I might as well not bother naming them at all.

- Names are no longer assumed to be alphanumeric. The Widget API allows any character, so I figure I need to as well. I will not support tweaks with duplicate names though.

- Many properties are being redone for various reasons, although many are because of the change in names. The current shorthand will still be available (hopefully, maybe, for some things) for tweaks/widgets that don't use spaces in their name though, and I advise everyone to abide by the standard alphanumeric pattern for naming things.

Templating

- Template has been renamed to Templates (with an s) since, like Points, Textures, FontStrings, etc, it's designed to take a table. In this case, each item in the table should be the name of a tweak to inherit attributes from. Like with Points, the shorthand Templates = "BaseTweak" does work if there's only one tweak to inherit from (and it's likely less memory use).

- InheritsFrom has been added, and only applies to tweaks that are creating new objects. It specifies what standard WoW widget should be inherited from: CreateFrame(Type, Name, Parent, InheritsFrom)

Requirements

- Requirements has been added and works like Templates and Points in that it can be a table of string values or just a string if there's one value. Requirements are those widgets that must exist before the tweak can be processed. If you're creating a tweak for a widget that may not exist yet, you can specify as much with: { Name = "DelayedWidget", Requirements = "DelayedWidget" } -- the tweak won't be processed until the widget exists, at which point the tweak will apply itself to that widget instead of creating a new one.

Scripts/Functions

- OnLoad is no longer called as soon as a tweak is processed. Instead, Startup is a new supported attribute of tweaks, and defines a function to call at this same point in time.

Timers

- Timers is a new attribute, and defines a list of timers. The advantage here is that there's a single function handling timer execution, the user doesn't need to track elapsed time manually every place that a periodic event is needed.

Code:
Timers = {
  {
    Name = <string>,
    Interval = <number>,
    Function = <function (self, elapsed)>
  },
  {
    Name = <string>,
    ...
  },
  ...
}
Name is optional and currently doesn't have a use. Interval defaults to 0, which means to repeat as often as possible. Function is called whenever the elapsed time meets or exceeds the Interval and then elapsed time is reset.

Custom Attributes

- Custom attributes can no longer be defined in the main area of the Tweak. Instead, the CustomAttributes attribute has been defined and can hold any custom data that needs to be propagated to the widget.
Code:
{
  Name = "MyTweak",
  CustomAttributes = {
    myBool = true,
    myInt = 2,
    myFunc = function() end,
    ...
  },
  ...
}
The resulting widget will have the CustomAttributes accessible at its base level, MyTweak.myBool, MyTweak.myInt, myTweak.myFunc, etc.



DESCRIPTION
Tweaker is the public start of an experiment in addon design. I love having options, but giving options to addons is a complicated process. Libraries have been written to simplify things for addon authors, but the mechanics behind them are still rather involved. I currently have over 200 folders in my AddOns directory. I have over 30 megs of SavedVariable files for my main toon. I need a change, and I imagine others do as well (for more of my thoughts on this, please visit my blog post entitled New Addon Design).

When it comes to the appearance of something, I want as many options available to me as the WoW Widget API will allow. Obviously, it's not practical to include that many settings in any addon. I started to use panel addons to give myself some flexibility. I couldn't modify existing things, but I could create panels, and they looked neat.

Tweaker started off that way. Like other panel addons, it could create panels of varying sizes and colors. Images and text could be added. Unlike many though, multiple images and text strings could be added to a single panel. Everything could be positioned not with just a single anchor, but with many anchors. It grew to the point that the entire widget API was exposed. I was only using half as much memory as my previous panel addon, but I still wanted more out of it.

So I added event handling. It was simple to do, and simpler to use. With panels being able to respond to events, they could change dynamically. I had been using a LDB display plugin along with a data plugin to display my current zone somewhere other than over the minimap. I decided to use Tweaker to create a frame for it instead. My own code ended up with a much smaller memory footprint (virtually none) and it was able to change the color of the text based on if the area was friendly, hostile, neutral, or whatever just like the tooltip for the minimap's zone panel. I also have it designed to show both the primary and sub zone names. Well, there's one addon I can get rid of now.

I moved on to create one for showing my coordinates. Got rid of an old addon for that. Another for the current time. And dropped another addon.

I then figured I could create buttons just as easily as panels, so I made a button for my calendar, and an icon for my mail. I also wanted a way to easily see if I was at the defense minimum and if I was hit or expertise capped, so I created a panel for that info too.

All these things are currently in my screenshot on the right. The arrow is from TomTom, and it fits quite nicely where it is. I plan to add more later.

None of these things were difficult to do, but this addon isn't for everyone either. It's not user friendly. It will take me time to write up appropriate documentation. I also intend on writing a number of tutorials for the things I've mentioned above, and more. But if you're like me and you like to tweak things, give Tweaker a try. Leave comments with any questions or suggestions you have, and I'll try to get some documentation and tutorials out as quickly as I can.

Some important notes for the time being:
- If you supply the name of an existing UI element, tweaker will operate on that element instead of creating a new one.
- If you declare an element with Virtual = true listed in its properties, it will not be created in the game but will instead remain "virtual" (this is handy for inheritance)
- For any element, you can create a Templates property. This property takes an array of elements (by name) to inherit from. Example: Templates = { "BasePanel", "TextPanel" } will inherit the properties of BasePanel and then those of TextPanel. Only properties that aren't defined in the inheriting tweak are inherited.
- There's not much error checking. That adds overhead that I'd prefer to avoid. If you do mess things up, a simple reloadui should fix them. There is some logging by calling Tweaker:SetGlobalLogLevel(level) where level can be "trace", "debug", "info", "warn", "error", or "fatal" -- all higher levels are also logged and tweak-specific levels can be declared by setting the LogLevel property of a tweak to one of the above levels as well.

DIRECTIONS
- Download and extract to Interface\Addons like normal
- In the Tweaker folder, create a file named config.lua
- In config.lua, call Tweaker:RegisterTweaks with an array of tables
- Populate the tables in a manner similar to the example below

EXAMPLE config.lua
Code:
Tweaker:RegisterTweaks({
    {
        Name = "SamplePanel",
        Parent = "UIParent",
        FrameStrata = "BACKGROUND",
        FrameLevel = 2,
        Points = {
            "CENTER",
        },
        Width = 200,
        Height = 50,
        Textures = {
            {
                Name = "$parentBorder",
                DrawLayer = "BACKGROUND",
                Texture = "0.12 0.12 0.12",
                Points = {
                    "TOPLEFT -3 3",
                    "BOTTOMRIGHT 3 -3",
                },
            },
            {
                Name = "$parentBackground",
                DrawLayer = "BORDER",
                Texture = "0.05 0.05 0.05",
                Points = "ALL",
            },
        },
        FontStrings = {
            {
                Name = "$parentText",
                Font = "Fonts\FRIZQT__.TTF 12 OUTLINE",
                JustifyH = "CENTER",
                JustifyV = "MIDDLE",
                Points = "ALL",
                Text = "Sample",
            },
        },
    },
})

1.2.2
- Backdrop now works -- every other widget API call I've seen takes a set of arguments but this one takes a table, hooray for consistency
- Consequently, I also put some dirty code in so that BackdropColorand BackdropBorderColor are called after Backdrop -- otherwise they don't work. It's messy and they actually get called twice now and I'm sure there are more scenarios that will need similar behavior but it'll do for now until I get some standardized code in to handle these scenarios.


1.2.1
- Added some additional tweaker-level logging
- Fixed the logger to colorize its messages
- Fixed Tweaker.util.unpack_if_table to return all unpacked values instead of just the first -- this consequently fixes some other issues, such as requiring all templates and requirements properly instead of just the first in each list


1.2.0

Core

- Instead of creating tweaks in Tweaker_Data, tweaks can now be created and registered via Tweaker:RegisterTweak or Tweaker:RegisterTweaks at any time. This creates the possibility to package tweaks as separate addons and avoids the chance of me accidentally packaging config.lua and overwriting yours. config.lua can still be used, but Tweaker_Data is no longer read from.

Coloring

-


1.1.2
* Fixed a bug that I apparently imagined fixing before -- provided you define a font, Tweaker should set it before trying to set text now. Thanks kellewic.

1.1.1
* First of many oversights, I'm sure. If you RegisterForDrag but don't SetMovable, then you get an error! Joy of joys... I've updated Tweaker to also call SetMovable(true) when defining a drag event.

1.1.0
* Added SecureHooks functionality. SecureHooks = { funcName = function() end } will create a secure hook to an existing function on an existing widget.
* Added DragEvent detection. When creating OnDragStart and OnDragStop events, Tweaker will automatically call RegisterForDrag("LeftButton"). If you want to drag with other buttons, it's up to you to handle that.
* Reworked the way that properties are handled from the config. Previously, any property was assumed to be an existing function on the widget, Parent = frame:SetParent(value), Hide = frame:Hide(), etc. Tweaker now supports custom properties so users can do MyCoolFunc = function() end and have widget.MyCoolFunc exist. Also works with scalars. MyCoolString = "hello!" will create widget.MyCoolString.
Optional Files (0)


Post A Reply Comment Options
Unread 09-04-09, 12:59 PM  
Faraque
A Theradrim Guardian
 
Faraque's Avatar
AddOn Author - Click to view AddOns

Forum posts: 68
File comments: 105
Uploads: 1
This looks very impressive. I do not process code well, so I wouldn't be able to make heads or tails of setup. The framework you've set up could be the start of something huge. Be sure to get people in the forums interested in your project here.
__________________
"imo Fara raged and gave Joker his scars" - Blueninja of Shadowmoon
Report comment to moderator  
Reply With Quote
Unread 09-13-09, 11:40 AM  
kellewic
Premium Member
 
kellewic's Avatar
Premium Member
AddOn Author - Click to view AddOns

Forum posts: 2
File comments: 131
Uploads: 4
Event

As I was playing with this and making a simple coordinates frame, I noticed you can't register the PLAYER_LOGIN event (well you can, but it won't fire).

This is because Tweaker does all the constructing in its PLAYER_LOGIN event and so WoW has already fired the event chain.

I made a change inside CreatePanels() to fix the issue if you are interested:

Code:
if string.sub(event, 1, 2) == "ON" then
	frame:SetScript(event, func)
else
        -- This entire function is run inside Tweaker's PLAYER_LOGIN event so if
        -- we try to register our own, we missed the boat so check for it here
        if event == "PLAYER_LOGIN" then
	        func(frame, event)
        else
	        frame.events = frame.events or {}
	        frame.events[event] = func
	        frame:RegisterEvent(event)
        end
end
Report comment to moderator  
Reply With Quote
Unread 09-13-09, 12:12 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
Re: Event

Thanks kellewic. That's probably a good idea until I get a better solution in there.

Tweaker is delayed until PLAYER_LOGIN so that you can work with widgets created by other addons. I was originally going to "queue" up things until the parent existed, but I was concerned with the performance hit of running code every OnUpdate. It might be worthwhile to reexamine it now since it'll be more necessary for some future plans.

Oh, and nice comment in the code there. Made me chuckle.
Last edited by Ahm : 09-13-09 at 12:15 PM.
Report comment to moderator  
Reply With Quote
Unread 09-13-09, 01:21 PM  
kellewic
Premium Member
 
kellewic's Avatar
Premium Member
AddOn Author - Click to view AddOns

Forum posts: 2
File comments: 131
Uploads: 4
Re: Re: Event

Originally posted by RaeVanMorlock
Thanks kellewic. That's probably a good idea until I get a better solution in there.

Tweaker is delayed until PLAYER_LOGIN so that you can work with widgets created by other addons. I was originally going to "queue" up things until the parent existed, but I was concerned with the performance hit of running code every OnUpdate. It might be worthwhile to reexamine it now since it'll be more necessary for some future plans.

Oh, and nice comment in the code there. Made me chuckle.
Since I posted, I've been playing with it more... I think you can still get access to other mods during PLAYER_LOGIN without Tweaker actually having to register anything (or even create its frame).

I was messing with the concept of many mods registering Tweaks, which is difficult now since you only have the one global Tweaker_Data table. This assumes everything is created at once and makes it hard to share tweaks with other people (without directly messing with Tweaker_Data, which will get ugly fast).

I made an addon in a separate directory called "kell_Tweaker" with a TOC file of:

Code:
## Interface: 30200
## Title: kell_Tweaker
## Author: kellewic
## Version: 1.0.0
## Notes: Tweaker configuration for kellewic
## Dependencies: Tweaker

kell_Tweaker.lua
Now, my configuration file depends on Tweaker being loaded.

and I changed Tweaker's TOC file to:

Code:
## Interface: 30200
## Title: Tweaker
## Author: raevanmorlock
## Version: 1.0.0
## Notes: Allows you to tweak your UI in any way you can imagine
## SavedVariables: TweakerDB

Tweaker.lua
Bsaically, I removed the config.lua since if you change Tweaker and I'm not thinking about it, I would likely overwrite my config.lua and be all sorts of angry

Inside Tweaker.lua, I made a few changes so I could create a Tweak whenever I wanted to after Tweaker was loaded. Only changes are shown here:

Code:
Tweaker = {}
local panels = {}
local panelNum = 0

...

-- Changed this so it's not looping every time
local function GetPanelByName(name)
	return panels[name]
end

...

local AttributesToSkip = {
	Name = true,
	Virtual = true,
	Debug = true,    -- ADDED
}

...

-- New method
function Tweaker:RegisterTweaks(tweaks)
	for _, panel in ipairs(tweaks) do
		self:RegisterTweak(panel)
	end
end

-- New method (replaced the original one called in PLAYER_LOGIN)
function Tweaker:RegisterTweak(panel)
	-- Set debug to panel setting
	debugMode = panel.Debug or Tweaker_DebugMode

	if GetPanelByName(panel.Name) then
		error(format("Panel %s already exists!", panel.Name), 2)
	end
	
	-- Insert panel into panel cache
	panels[panel.Name] = panel
	
	if not panel.Virtual then
		PerformPanelInheritance(panel)
		
		local frameParent = panel.Parent or "UIParent"
		local frameType = panel.ObjectType or "FRAME"
		local frameName = CreateWidgetName(panel.Name, frameParent)
		
		-- No frame name, create a default one (CHANGE)
		if not frameName then
			frameName = "TweakerPanel"..panelNum
			panelNum = panelNum + 1
		end
		
		DPrint("|cffff0000"..(_G[frameName] and "Grabbing" or "Creating").." "..(string.lower(frameType)).." "..frameName.."|r")
		local frame = _G[frameName] or CreateFrame(frameType, frameName, _G[frameParent], panel.Template)
		SetAttributes(frame, panel)
		
		if panel.Textures then
			for i,texture in ipairs(panel.Textures) do
				local name = CreateWidgetName(texture.Name or "$parentTexture"..i, frameName)
				DPrint("|cff00ff00"..(_G[name] and "Grabbing" or "Creating").." texture "..name.."|r")
				local t = _G[name] or frame:CreateTexture(name, texture.DrawLayer or "ARTWORK", texture.Template)
				SetAttributes(t, texture)
			end
		end
		
		if panel.FontStrings then
			for i,fontstring in ipairs(panel.FontStrings) do
				local name = CreateWidgetName(fontstring.Name or "$parentFontString"..i, frameName)
				DPrint("|cff00ff00"..(_G[name] and "Grabbing" or "Creating").." fontstring "..name.."|r")
				local fs = _G[name] or frame:CreateFontString(name, fontstring.DrawLayer or "OVERLAY", fontstring.Template)
				SetAttributes(fs, fontstring)
			end
		end
		
		if panel.SecureHooks then
			for hooklist,func in pairs(panel.SecureHooks) do
				for _,hook in pairs({string.split(",", hooklist)}) do
					hook = trim(hook)
					hooksecurefunc(frame, hook, func)
				end
			end
		end

		if panel.Events then
			for eventlist,func in pairs(panel.Events) do				
				for _,event in pairs({string.split(",", eventlist)}) do						
					event = trim(string.upper(event))
					
					if KeyboardEvents[event] then frame:EnableKeyboard(true) end
					if MouseEvents[event] then frame:EnableMouse(true) end
					if MouseWheelEvents[event] then frame:EnableMouseWheel(true) end
					
					if DragEvents[event] then
						frame:RegisterForDrag("LeftButton")
						frame:SetMovable(true)
					end
					
					if string.sub(event, 1, 2) == "ON" then
						frame:SetScript(event, func)
					else
						frame.events = frame.events or {}
						frame.events[event] = func
						frame:RegisterEvent(event)
					end
				end
			end
			
			if frame.events then
				frame:SetScript("OnEvent", function(self, event, ...)
					self.events = self.events or {}
					if type(self.events[event]) == "function" then
						self.events[event](self, event, ...)
					end
				end)
			end
			
			if frame:IsMouseEnabled() and frame.RegisterForClicks then
				frame:RegisterForClicks("AnyUp")
			end
			
			local f = panel.Events.OnLoad
			if f then f(frame) end
		end
	end

	-- Set debug mode back to global value
	debugMode = Tweaker_DebugMode or false
end

-- REMOVED FRAME CREATION CODE AND EVENTS
So now, it all becomes:

Code:
-- Single panel
Tweaker:RegisterTweak(
	{
		Name = "Tester1",
		Width = 80,
		Height = 15,
		Points = { "CENTER" },
		ClampedToScreen = true,
		Textures = {
			{
				DrawLayer = "BACKGROUND",
				Texture = "0 0 0",
			},
		},
		FontStrings = {
			{
				Name = "$parentText",
				Font = "Fonts\\FRIZQT__.ttf 10",
				Text = "TEST"
			},
		},
	}
)

-- Multiple panels just like the original function call
Tweaker:RegisterTweaks({
	{
		Name = "Tester1",
		Width = 80,
		Height = 15,
		Points = { "CENTER" },
		ClampedToScreen = true,
		Textures = {
			{
				DrawLayer = "BACKGROUND",
				Texture = "0 0 0",
			},
		},
		FontStrings = {
			{
				Name = "$parentText",
				Font = "Fonts\\FRIZQT__.ttf 10",
				Text = "TEST1"
			},
		},
	},
	{
		Name = "Tester2",
		Width = 80,
		Height = 15,
		Points = { "CENTER" },
		ClampedToScreen = true,
		Textures = {
			{
				DrawLayer = "BACKGROUND",
				Texture = "0 0 0",
			},
		},
		FontStrings = {
			{
				Name = "$parentText",
				Font = "Fonts\\FRIZQT__.ttf 10",
				Text = "TEST2"
			},
		},
	},
})

So I could still access other mods by creating my own PLAYER_LOGIN event since Tweaker will call that as any other event without the custom code I posted earlier. So it should be possible to do:

Code:
Tweaker:RegisterTweak(
	{
		Name = "Tester2",
		Width = 80,
		Height = 15,
		Points = { "CENTER" },
		ClampedToScreen = true,
		Textures = {
			{
				DrawLayer = "BACKGROUND",
				Texture = "0 0 0",
			},
		},
		FontStrings = {
			{
				Name = "$parentText",
				Font = "Fonts\\FRIZQT__.ttf 10",
				Text = "TEST2"
			},
		},
                Events = {
			PLAYER_LOGIN = function(self)
				Tweaker:RegisterTweak({
                                        -- Whatever addon widget you want to mess with
                                })
			end,
                },
	}
)
Report comment to moderator  
Reply With Quote
Unread 09-13-09, 03:27 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
Re: Re: Re: Event

Well I'm glad to see somebody enjoying Tweaker

That's definitely taking it further faster than I had planned, but I like it. I appreciate it.

In fact, it's inspired me to reevaluate Tweaker at this stage in development. It's a long post, but I've written about the birth of tweaker and expressed what's going through my mind at this juncture. I'd really appreciate some feedback from you and everyone visiting these comments... either leave your thoughts here or on the blog, it doesn't matter.

I think 1.2 is going to be very big for Tweaker.
Report comment to moderator  
Reply With Quote
Unread 09-13-09, 07:44 PM  
kellewic
Premium Member
 
kellewic's Avatar
Premium Member
AddOn Author - Click to view AddOns

Forum posts: 2
File comments: 131
Uploads: 4
Re: Re: Re: Re: Event

Originally posted by RaeVanMorlock
Well I'm glad to see somebody enjoying Tweaker

That's definitely taking it further faster than I had planned, but I like it. I appreciate it.

In fact, it's inspired me to reevaluate Tweaker at this stage in development. It's a long post, but I've written about the birth of tweaker and expressed what's going through my mind at this juncture. I'd really appreciate some feedback from you and everyone visiting these comments... either leave your thoughts here or on the blog, it doesn't matter.

I think 1.2 is going to be very big for Tweaker.
I sent you an email; had too much to say


EDIT

I noticed there is a bug in the code I emailed:

Code:
local noop = function end
should be:

Code:
local noop = function() end
I've been up like 36 hours now so...
Last edited by kellewic : 09-13-09 at 08:14 PM.
Report comment to moderator  
Reply With Quote
Unread 09-13-09, 10:47 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
Re: Re: Re: Re: Re: Event

Originally posted by kellewic
I noticed there is a bug in the code I emailed:

Code:
local noop = function end
should be:

Code:
local noop = function() end
I've been up like 36 hours now so...
Lol, yes, I found it. No worries.

I emailed you back a little while ago. About to start some testing and see where I want to start with this lengthy list of changes.

Get some sleep!
Last edited by Ahm : 09-13-09 at 10:47 PM.
Report comment to moderator  
Reply With Quote
Unread 09-15-09, 10:24 PM  
kellewic
Premium Member
 
kellewic's Avatar
Premium Member
AddOn Author - Click to view AddOns

Forum posts: 2
File comments: 131
Uploads: 4
Font issue

Found a potential problem with FontStrings. I have the following configuration:

Code:
local tweakName = "kell_Coords"

Tweaker:RegisterTweak({
	Name = "kell_BasePanelTemplate",
	Virtual = true,
	Width = 80,
	Height = 13,
	Points = {"CENTER"},
	ClampedToScreen = true,
	Textures = {
		{
			DrawLayer = "BACKGROUND",
			Texture = "0 0 0",
		},
	},
	FontStrings = {
		{
			Name = "$parentText",
			Font = "Fonts\\FRIZQT__.ttf 10",
		},
	},
	Events = {			
		OnDragStart = true,
		
		OnDragStop = function(self)
			self:StopMovingOrSizing()
			--save_points(self)
		end,
		
		PLAYER_LOGIN = function(self)
			--get_coords()
			--set_points(self)
		end,
	},
})

Tweaker:RegisterTweaks({
	{
		Template = "kell_BasePanelTemplate",
		Debug = true,
		Name = tweakName,

		FontStrings = {
			{
				Name = tweakName .. "Text",
				Font = "Fonts\\FRIZQT__.ttf 10",
			},
		},
	},

	{
		Template = "kell_BasePanelTemplate",
		Debug = true,
		Name = tweakName .. "1",
		FontStrings = {
			{
				Name = "$parentText",
				Text = "TEST"
			},
		},
	}
})
I end up with an error on Tweaker trying to build up kell_Coords1Text since it is trying to call $parentText:SetText("TEST") before assigning the Font to the FontString. Since there is no assigned font, it can't set a text value.

This means Tweaker will have to ensure a Font is assigned before SetText is called.
Report comment to moderator  
Reply With Quote
Unread 09-15-09, 11:35 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
Re: Font issue

Originally posted by kellewic
...

I end up with an error on Tweaker trying to build up kell_Coords1Text since it is trying to call $parentText:SetText("TEST") before assigning the Font to the FontString. Since there is no assigned font, it can't set a text value.

This means Tweaker will have to ensure a Font is assigned before SetText is called.
Hm.. I thought I had accounted for that. Thanks for the report. I'll release 1.1.2 in a bit to fix it. *fingers crossed*
Report comment to moderator  
Reply With Quote
Unread 09-17-09, 08:02 PM  
kellewic
Premium Member
 
kellewic's Avatar
Premium Member
AddOn Author - Click to view AddOns

Forum posts: 2
File comments: 131
Uploads: 4
Nice update

Nice update on the front page

If you have any code you want tested, shoot me an email and I'd be happy to check it out.
Report comment to moderator  
Reply With Quote
Unread 09-17-09, 09:18 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
Re: Nice update

Originally posted by kellewic
Nice update on the front page

If you have any code you want tested, shoot me an email and I'd be happy to check it out.
Thanks, kell!

The Tweaker site isn't ready for public release yet, but, since it is up on the web, I took the opportunity to learn how to deliver .zip files from it so anyone interested can just grab the zip: http://tweakeraddon.appspot.com/Tweaker-Dev-Dump.zip

The link is also on the main page now. I might make more packages like this in the future, so be sure to check the main page for their announcements.

Gosh, when did the sun go down? I wish I had music to listen to while I work instead of movies to watch.. it'd probably be less distracting.
Report comment to moderator  
Reply With Quote
Unread 09-18-09, 10:02 PM  
kellewic
Premium Member
 
kellewic's Avatar
Premium Member
AddOn Author - Click to view AddOns

Forum posts: 2
File comments: 131
Uploads: 4
Re: Re: Nice update

Originally posted by RaeVanMorlock
Thanks, kell!

The Tweaker site isn't ready for public release yet, but, since it is up on the web, I took the opportunity to learn how to deliver .zip files from it so anyone interested can just grab the zip: http://tweakeraddon.appspot.com/Tweaker-Dev-Dump.zip

The link is also on the main page now. I might make more packages like this in the future, so be sure to check the main page for their announcements.

Gosh, when did the sun go down? I wish I had music to listen to while I work instead of movies to watch.. it'd probably be less distracting.
Running /dump through its paces and got:

Code:
[2009/09/18 20:13:14-322-x1]: Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:110: invalid order function for sorting
Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:110: in function <...terface\AddOns\Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:108>
Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:143: in function <...terface\AddOns\Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:117>
(tail call): ?:
Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:181: in function `Dump'
<string>:"Tweaker.Dump( {1,2,3,4})":1: in function `f'
Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:208: in function `value'
Interface\FrameXML\ChatFrame.lua:3529: in function `ChatEdit_ParseText':
Interface\FrameXML\ChatFrame.lua:3177: in function `ChatEdit_SendText':
Interface\FrameXML\ChatFrame.lua:3201: in function `ChatEdit_OnEnterPressed':
<string>:"*:OnEnterPressed":1: in function <[string "*:OnEnterPressed"]:1>
What I did was the following in-game:

Code:
/run LL = {1,2,3,4,5}
/tweaker dump LL
Report comment to moderator  
Reply With Quote
Unread 09-18-09, 11:11 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
Re: Re: Re: Nice update

Originally posted by kellewic
Running /dump through its paces and got:

Code:
[2009/09/18 20:13:14-322-x1]: Tweaker-Dev-Dump\Tweaker-Dev-Dump.lua:110: invalid order function for sorting
...
What I did was the following in-game:

Code:
/run LL = {1,2,3,4,5}
/tweaker dump LL
So I'm a big fan of the iif shorthand.. which equates to: val = <condition> and <valueA> or <valueB> in lua... but, apparently, not exactly.. because if valueA is false, then it sends valueB.. even if the condition was true.

So in the following:
Code:
local function get_sorted_keys(...)
    local keys, keyCount = get_keys(...)
    table.sort(keys, function(a,b)
        local ta,tb = type(a),type(b)
        return ta==tb and a < b or ta=="number"
    end)
    return keys, keyCount
end
.. obviously had some problems with {1, 2, 3, 4} -- essentially, the types always matched, but if a < b, it'd still return true because ta=="number" -- so everything was less than everything else... and the sort epic failed.

I'll probably make my own iif() function for future use, but for now.. make the fix yourself or download the updated copy from the main page (same url as before).

Thanks!!

Code:
local function get_sorted_keys(...)
    local keys, keyCount = get_keys(...)
    table.sort(keys, function(a,b)
        local ta,tb = type(a),type(b)
        if ta==tb then
            return a < b
        end
        return ta=="number"
    end)
    return keys, keyCount
end
Report comment to moderator  
Reply With Quote
Unread 09-19-09, 02:42 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
Tweaker-Dev-Dump update

The Tweaker-Dev-Dump package has been updated again.

I had a hunch that /dump _G was freezing up WoW because of get_global_name... I haven't taken the time to really analyze the code, but that was my hunch, and I made code changes so that it would do things slightly differently when dealing with _G in order to account for it.

Happy to say, /dump _G works now.

There's about a one second delay or so on my system... I imagine it takes time to grab and sort over 30,000 keys... but it's certainly bearable if you really need to dump _G. Interestingly, whether I dump 20 values or 200 at a time, the delay seems to be about the same. I imagine that could be worse if I figure out how to have function dumps include more info.. but I like to keep the default at 20 anyhow or else you're scrolling way up just to scroll back down through the list. An even smaller value might be better so you don't have to scroll at all... but that's why it's a global.. so you can decide for yourself through Tweaker.DumpSize.

Ciao!
Last edited by Ahm : 11-02-09 at 09:21 AM.
Report comment to moderator  
Reply With Quote
Unread 09-19-09, 03:34 PM  
Ahm
A Fallenroot Satyr
AddOn Author - Click to view AddOns

Forum posts: 20
File comments: 64
Uploads: 6
iif() fail

So... there's a problem with iif() now

Using <condition> and <valueA> or <valueB>

The values are only calculated if they need to be, so everything is happy.

Using iif().. everything is calculated right away in order to send the results to the function... so a < b doesn't work so well anymore when a and b are not the same type.

You may not want to download the current package just yet...
Report comment to moderator  
Reply With Quote
Post A Reply



Category Jump: